Skip to content

Commit e179414

Browse files
digitalkaozRobert Schönthal
and
Robert Schönthal
authored
feat(dns): use dns resolvers to for dns failover routing scenarios (#4)
Co-authored-by: Robert Schönthal <[email protected]>
1 parent 86f30ce commit e179414

File tree

4 files changed

+98
-26
lines changed

4 files changed

+98
-26
lines changed

.github/workflows/test.yaml

+68-19
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ jobs:
6060
docker logs statista_proxy
6161
6262
- name: Test Docker Image with Cookie Strategy without cookie
63+
id: test-cookie-no-cookie
64+
continue-on-error: true
6365
run: |
6466
curl -Is localhost:80 | grep -i -e "x-proxy-flow: route-to-legacy"
6567
6668
- name: Test Docker Image with Cookie Strategy with cookie
69+
continue-on-error: true
6770
run: |
6871
curl -Is --cookie "my_app_routing=new" localhost:80 | grep -i -e "x-proxy-flow: route-to-new"
6972
@@ -86,18 +89,26 @@ jobs:
8689
docker logs statista_proxy
8790
8891
- name: Test Docker Image with Percentage Strategy backend selection
92+
id: test-percentage-strategy
93+
continue-on-error: true
8994
run: |
9095
curl -Is localhost:80 | grep -i -e "x-proxy-flow: route-to-percentage"
9196
9297
- name: Test Docker Image with Percentage Strategy with sticky cookie on old domain
98+
id: test-percentage-sticky-old-domain
99+
continue-on-error: true
93100
run: |
94101
curl -Is localhost:80 --cookie "my_app=old_domain" | grep -i -e "server: Apache"
95102
96103
- name: Test Docker Image with Percentage Strategy with sticky cookie on new domain
104+
id: test-percentage-sticky-new-domain
105+
continue-on-error: true
97106
run: |
98107
curl -Is localhost:80 --cookie "my_app=new_domain" | grep -i -e "x-served-by: cache-"
99108
100109
- name: Test Docker Image with Percentage Strategy with round robin
110+
id: test-percentage-round-robin
111+
continue-on-error: true
101112
# sadly we dont know which server serves us first, so we have to check both
102113
run: |
103114
curl -Is localhost:80 | grep -i -e "server:" -e "x-served-by:" -e "set-cookie: my_app=new_domain; path=/" -e "set-cookie: my_app=old_domain; path=/"
@@ -107,53 +118,91 @@ jobs:
107118
if: success() || failure()
108119
run: docker rm -f statista_proxy
109120

121+
# validation TEMPLATE
122+
#- name: name of the test
123+
# timeout-minutes: 1 # set so if the command runs successfully the test will fail
124+
# id: test-validation-percentage-new # important since all steps run and we collect the failure at then end
125+
# continue-on-error: true # important for allowing other steps to be run regardless of this one which might fail
126+
# run: |
127+
# ! docker run \ # important simply negate the exit code, since we expect the container to fail (which means succesfull validation)
128+
# -e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 \
129+
# "${{ env.IMAGE_NAME }}"
130+
110131
# variable validation
111132
- name: Run Docker Image with Invalid new Percentage
133+
timeout-minutes: 1
134+
id: test-validation-percentage-new
135+
continue-on-error: true
112136
run: |
113-
set +e
114-
115-
docker run \
137+
! docker run \
116138
-e STRATEGY=PERCENTAGE \
117139
-e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 \
118140
-e PERCENTAGE_NEW=foo -e PERCENTAGE_OLD=50 \
119141
-e COOKIE_PERCENTAGE_NAME=my_app \
120142
"${{ env.IMAGE_NAME }}"
121143
122-
if [[ $? == 1 ]]; then exit 0; else exit 1; fi
123-
124144
- name: Run Docker Image with Invalid old Percentage
145+
timeout-minutes: 1
146+
id: test-validation-percentage-old
147+
continue-on-error: true
125148
run: |
126-
set +e
127-
128-
docker run \
149+
! docker run \
129150
-e STRATEGY=PERCENTAGE \
130151
-e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 \
131152
-e PERCENTAGE_NEW=50 -e PERCENTAGE_OLD=foo \
132153
-e COOKIE_PERCENTAGE_NAME=my_app \
133154
"${{ env.IMAGE_NAME }}"
134155
135-
if [[ $? == 1 ]]; then exit 0; else exit 1; fi
136-
137156
- name: Run Docker Image with Invalid old domain
157+
timeout-minutes: 1
158+
id: test-validation-old-domain
159+
continue-on-error: true
138160
run: |
139-
set +e
140-
141-
docker run \
161+
! docker run \
142162
-e STRATEGY=PERCENTAGE \
143163
-e NEW_DOMAIN=apache.org:443 \
144164
-e COOKIE_PERCENTAGE_NAME=my_app \
145165
"${{ env.IMAGE_NAME }}"
146166
147-
if [[ $? == 1 ]]; then exit 0; else exit 1; fi
148-
149167
- name: Run Docker Image with Invalid new domain
168+
timeout-minutes: 1
169+
id: test-validation-new-domain
170+
continue-on-error: true
150171
run: |
151-
set +e
152-
153-
docker run \
172+
! docker run \
154173
-e STRATEGY=PERCENTAGE \
155174
-e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:lol \
156175
-e COOKIE_PERCENTAGE_NAME=my_app \
157176
"${{ env.IMAGE_NAME }}"
158177
159-
if [[ $? == 1 ]]; then exit 0; else exit 1; fi
178+
- name: Run Docker Image with Invalid server count
179+
timeout-minutes: 1
180+
id: test-validation-server-count
181+
continue-on-error: true
182+
run: |
183+
! docker run \
184+
-e STRATEGY=PERCENTAGE \
185+
-e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 \
186+
-e COOKIE_PERCENTAGE_NAME=my_app \
187+
-e SERVER_COUNT=foo \
188+
"${{ env.IMAGE_NAME }}"
189+
190+
- name: Run Docker Image with Invalid DNS Resolver
191+
timeout-minutes: 1
192+
id: test-validation-dns-resolver
193+
continue-on-error: true
194+
run: |
195+
! docker run \
196+
-e STRATEGY=PERCENTAGE \
197+
-e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 \
198+
-e COOKIE_PERCENTAGE_NAME=my_app \
199+
-e DNS_RESOLVER=foo \
200+
"${{ env.IMAGE_NAME }}"
201+
202+
- name: Check for failures
203+
if: always()
204+
env:
205+
STEPS_CONTEXT: ${{ toJson(steps) }}
206+
run: |
207+
set +e
208+
! echo "$STEPS_CONTEXT" | grep -q 'failure'

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM haproxy:lts-alpine
22

3-
LABEL org.opencontainers.image.source=https://github.com/statista-oss/proxy-router
3+
LABEL org.opencontainers.image.source="https://github.com/statista-oss/proxy-router"
44
LABEL org.opencontainers.image.description="haproxy configurable through env vars for different routing strategies"
55

66
USER root

README.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ how much traffic should be routed to the old application
4141
### PERCENTAGE_NEW
4242
how much traffic should be routed to the new application
4343

44+
### DNS_RESOLVER (optional, default=1.1.1.1)
45+
The DNS resolver to use for resolving the domain names to IP addresses.
46+
If you want to reroute internal traffic you might want to change that.
47+
48+
### SERVER_COUNT (optional, default=5)
49+
as we are using DNS Resolver we try to create a server for each IP address we get back from the DNS query.
50+
This is the maximum amount of servers we will create.
51+
4452

4553
## Local Testing
4654

@@ -54,7 +62,7 @@ docker build -t statista-proxy .
5462
run the container
5563

5664
```bash
57-
docker run -p80:80 -e STRATEGY=PERCENTAGE -e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 -e PERCENTAGE_NEW=50 -e PERCENTAGE_OLD=50 -e COOKIE_PERCENTAGE_NAME=my_app statista_proxy
65+
docker run -p80:80 -e STRATEGY=PERCENTAGE -e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 -e PERCENTAGE_NEW=50 -e PERCENTAGE_OLD=50 -e COOKIE_PERCENTAGE_NAME=my_app statista-proxy
5866
```
5967

6068
run requests (since its round robin every request should be flipped)
@@ -69,7 +77,7 @@ further requests made by the same client will stick to this server
6977
### Cookie based routing
7078

7179
```bash
72-
docker run -p80:80 -e STRATEGY=COOKIE -e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 -e COOKIE_STRATEGY_NAME="my_app_routing=new" statista_proxy
80+
docker run -p80:80 -e STRATEGY=COOKIE -e OLD_DOMAIN=haproxy.com:443 -e NEW_DOMAIN=apache.org:443 -e COOKIE_STRATEGY_NAME="my_app_routing=new" statista-proxy
7381
```
7482

7583
run requests (since its round robin every request should be flipped)

haproxy.cfg

+19-4
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,27 @@ global
1010
# default some environment variables
1111
presetenv PERCENTAGE_NEW "0"
1212
presetenv PERCENTAGE_OLD "100"
13+
presetenv SERVER_COUNT "5"
14+
presetenv DNS_RESOLVER "1.1.1.1:53"
1315

1416
# we source them from the environment here to actually typecheck them
1517
set-var proc.percentage_new int("${PERCENTAGE_NEW}")
1618
set-var proc.percentage_old int("${PERCENTAGE_OLD}")
1719

20+
set-var proc.server_count int("${SERVER_COUNT}")
21+
1822
#log stdout format raw local0
1923

2024
defaults
2125
timeout connect 5s
2226
timeout client 1m
2327
timeout server 1m
2428
mode http
29+
default-server check
30+
default-server resolvers dns
31+
default-server resolve-prefer ipv4
32+
default-server init-addr last,libc,none
33+
default-server ssl verify required ca-file @system-ca
2534
#log global
2635
#option httplog
2736

@@ -47,24 +56,30 @@ frontend http-in
4756
backend old_domain
4857
http-response set-header X-Proxy-Flow route-to-legacy
4958
option tcp-check
59+
balance leastconn
5060

51-
server default_old "$OLD_DOMAIN" check ssl verify none
61+
server-template default_old "$SERVER_COUNT" "$OLD_DOMAIN"
5262

5363
backend percentage_strategy
5464
http-response set-header X-Proxy-Flow route-to-percentage
5565
option tcp-check
66+
balance leastconn
5667

5768
cookie "$COOKIE_PERCENTAGE_NAME" insert indirect
5869

5970
# old domain
60-
server old_domain_percentage "$OLD_DOMAIN" check cookie old_domain ssl verify none weight "$PERCENTAGE_OLD"
71+
server-template old_domain_percentage "$SERVER_COUNT" "$OLD_DOMAIN" cookie old_domain weight "$PERCENTAGE_OLD"
6172

6273
# new domain
63-
server new_domain_percentage "$NEW_DOMAIN" check cookie new_domain ssl verify none weight "$PERCENTAGE_NEW"
74+
server-template new_domain_percentage "$SERVER_COUNT" "$NEW_DOMAIN" cookie new_domain weight "$PERCENTAGE_NEW"
6475

6576
backend cookie_strategy
77+
balance leastconn
6678
http-response set-header X-Proxy-Flow route-to-new
6779
option tcp-check
6880

69-
server default_new "$NEW_DOMAIN" check ssl verify none
81+
server-template default_new "$SERVER_COUNT" "$NEW_DOMAIN"
7082

83+
resolvers dns
84+
nameserver default "$DNS_RESOLVER"
85+
accepted_payload_size 8192

0 commit comments

Comments
 (0)