...
1import logging
2
3import pytest
4
5from tests.utils import econf_foreach_cluster
6
7logging.basicConfig(
8 level=logging.INFO,
9 format="%(asctime)s test %(levelname)s: %(message)s",
10 datefmt="%Y-%m-%d %H:%M:%S",
11)
12
13logger = logging.getLogger("ambassador")
14# logger.setLevel(logging.DEBUG)
15
16from ambassador import IR, Config, EnvoyConfig
17from ambassador.fetch import ResourceFetcher
18from ambassador.utils import NullSecretHandler
19from tests.utils import default_listener_manifests
20
21SERVICE_NAME = "coolsvcname"
22
23
24def _get_rl_config(yaml):
25 for listener in yaml["static_resources"]["listeners"]:
26 for filter_chain in listener["filter_chains"]:
27 for f in filter_chain["filters"]:
28 for http_filter in f["typed_config"]["http_filters"]:
29 if http_filter["name"] == "envoy.filters.http.ratelimit":
30 return http_filter
31 return False
32
33
34def _get_envoy_config(yaml, version="V2"):
35 aconf = Config()
36 fetcher = ResourceFetcher(logger, aconf)
37 fetcher.parse_yaml(default_listener_manifests() + yaml, k8s=True)
38
39 aconf.load_all(fetcher.sorted())
40
41 secret_handler = NullSecretHandler(logger, None, None, "0")
42
43 ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
44
45 assert ir
46 return EnvoyConfig.generate(ir, version)
47
48
49def _get_ratelimit_default_conf_v3():
50 return {
51 "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit",
52 "domain": "ambassador",
53 "request_type": "both",
54 "timeout": "0.020s",
55 "rate_limit_service": {
56 "transport_api_version": "V2",
57 "grpc_service": {
58 "envoy_grpc": {"cluster_name": "cluster_{}_default".format(SERVICE_NAME)}
59 },
60 },
61 }
62
63
64def _get_ratelimit_default_conf_v2():
65 return {
66 "@type": "type.googleapis.com/envoy.config.filter.http.rate_limit.v2.RateLimit",
67 "domain": "ambassador",
68 "request_type": "both",
69 "timeout": "0.020s",
70 "rate_limit_service": {
71 "grpc_service": {
72 "envoy_grpc": {"cluster_name": "cluster_{}_default".format(SERVICE_NAME)}
73 }
74 },
75 }
76
77
78@pytest.mark.compilertest
79def test_irratelimit_defaultsv3():
80 default_config = _get_ratelimit_default_conf_v3()
81
82 # Test all defaults
83 yaml = """
84apiVersion: getambassador.io/v3alpha1
85kind: RateLimitService
86metadata:
87 name: myrls
88 namespace: default
89spec:
90 service: {}
91""".format(
92 SERVICE_NAME
93 )
94 econf = _get_envoy_config(yaml, version="V3")
95 conf = _get_rl_config(econf.as_dict())
96
97 assert conf
98
99 assert conf.get("typed_config") == default_config
100
101
102@pytest.mark.compilertest
103def test_irratelimit_defaults():
104 default_config = _get_ratelimit_default_conf_v2()
105
106 # Test all defaults
107 yaml = """
108apiVersion: getambassador.io/v3alpha1
109kind: RateLimitService
110metadata:
111 name: myrls
112 namespace: default
113spec:
114 service: {}
115""".format(
116 SERVICE_NAME
117 )
118 econf = _get_envoy_config(yaml)
119 conf = _get_rl_config(econf.as_dict())
120
121 assert conf
122
123 assert conf.get("typed_config") == default_config
124
125
126@pytest.mark.compilertest
127def test_irratelimit_grpcsvc_version_v3():
128 # Test protocol_version override
129 yaml = """
130---
131apiVersion: getambassador.io/v3alpha1
132kind: RateLimitService
133metadata:
134 name: myrls
135 namespace: default
136spec:
137 service: {}
138 protocol_version: "v3"
139""".format(
140 SERVICE_NAME
141 )
142 config = _get_ratelimit_default_conf_v3()
143 config["rate_limit_service"]["transport_api_version"] = "V3"
144
145 econf = _get_envoy_config(yaml, version="V3")
146 conf = _get_rl_config(econf.as_dict())
147
148 assert conf
149
150 assert conf.get("typed_config") == config
151
152
153@pytest.mark.compilertest
154def test_irratelimit_cluster_fields_v3_config():
155
156 stats_name = "ratelimitservice"
157
158 yaml = """
159---
160apiVersion: getambassador.io/v3alpha1
161kind: RateLimitService
162metadata:
163 name: myrls
164 namespace: default
165spec:
166 service: {}
167 protocol_version: "v2"
168 stats_name: {}
169""".format(
170 SERVICE_NAME, stats_name
171 )
172
173 econf = _get_envoy_config(yaml, version="V3")
174 conf = _get_rl_config(econf.as_dict())
175
176 assert conf
177 assert conf.get("typed_config") == _get_ratelimit_default_conf_v3()
178
179 assert "ir.ratelimit" not in econf.ir.aconf.errors
180
181 def check_fields(cluster):
182 assert cluster["alt_stat_name"] == stats_name
183
184 econf_foreach_cluster(
185 econf.as_dict(), check_fields, name="cluster_{}_default".format(SERVICE_NAME)
186 )
187
188
189@pytest.mark.compilertest
190def test_irratelimit_cluster_fields_v2_config():
191
192 stats_name = "ratelimitservice"
193
194 yaml = """
195---
196apiVersion: getambassador.io/v3alpha1
197kind: RateLimitService
198metadata:
199 name: myrls
200 namespace: default
201spec:
202 service: {}
203 protocol_version: "v3"
204 stats_name: {}
205""".format(
206 SERVICE_NAME, stats_name
207 )
208
209 econf = _get_envoy_config(yaml)
210 conf = _get_rl_config(econf.as_dict())
211
212 assert conf
213 assert conf.get("typed_config") == _get_ratelimit_default_conf_v2()
214
215 assert "ir.ratelimit" not in econf.ir.aconf.errors
216
217 def check_fields(cluster):
218 assert cluster["alt_stat_name"] == stats_name
219
220 econf_foreach_cluster(
221 econf.as_dict(), check_fields, name="cluster_{}_default".format(SERVICE_NAME)
222 )
223
224
225@pytest.mark.compilertest
226def test_irratelimit_grpcsvc_version_v2():
227 # Test protocol_version override
228 yaml = """
229---
230apiVersion: getambassador.io/v3alpha1
231kind: RateLimitService
232metadata:
233 name: myrls
234 namespace: default
235spec:
236 service: {}
237 protocol_version: "v2"
238""".format(
239 SERVICE_NAME
240 )
241 config = _get_ratelimit_default_conf_v2()
242 econf = _get_envoy_config(yaml)
243 conf = _get_rl_config(econf.as_dict())
244
245 assert conf
246
247 assert conf.get("typed_config") == config
248
249
250@pytest.mark.compilertest
251def test_irratelimit_error():
252 # Test error no svc name
253 yaml = """
254---
255apiVersion: getambassador.io/v3alpha1
256kind: RateLimitService
257metadata:
258 name: myrls
259 namespace: default
260spec: {}
261"""
262 econf = _get_envoy_config(yaml)
263 conf = _get_rl_config(econf.as_dict())
264
265 assert not conf
266
267
268@pytest.mark.compilertest
269def test_irratelimit_error_v3():
270 # Test error no svc name
271 yaml = """
272---
273apiVersion: getambassador.io/v3alpha1
274kind: RateLimitService
275metadata:
276 name: myrls
277 namespace: default
278spec: {}
279"""
280 econf = _get_envoy_config(yaml, version="V3")
281 conf = _get_rl_config(econf.as_dict())
282
283 assert not conf
284
285
286@pytest.mark.compilertest
287def test_irratelimit_overrides():
288
289 # Test all other overrides
290 config = _get_ratelimit_default_conf_v2()
291 yaml = """
292---
293apiVersion: getambassador.io/v3alpha1
294kind: RateLimitService
295metadata:
296 name: myrls
297 namespace: someotherns
298spec:
299 service: {}
300 domain: otherdomain
301 timeout_ms: 500
302 tls: rl-tls-context
303 protocol_version: v2
304""".format(
305 SERVICE_NAME
306 )
307 config["rate_limit_service"]["grpc_service"]["envoy_grpc"][
308 "cluster_name"
309 ] = "cluster_{}_someotherns".format(SERVICE_NAME)
310 config["timeout"] = "0.500s"
311 config["domain"] = "otherdomain"
312
313 econf = _get_envoy_config(yaml)
314 conf = _get_rl_config(econf.as_dict())
315
316 assert conf
317 assert conf.get("typed_config") == config
318
319
320@pytest.mark.compilertest
321def test_irratelimit_overrides_v3():
322
323 # Test all other overrides
324 config = _get_ratelimit_default_conf_v3()
325 yaml = """
326---
327apiVersion: getambassador.io/v3alpha1
328kind: RateLimitService
329metadata:
330 name: myrls
331 namespace: someotherns
332spec:
333 service: {}
334 domain: otherdomain
335 timeout_ms: 500
336 tls: rl-tls-context
337 protocol_version: v2
338""".format(
339 SERVICE_NAME
340 )
341 config["rate_limit_service"]["grpc_service"]["envoy_grpc"][
342 "cluster_name"
343 ] = "cluster_{}_someotherns".format(SERVICE_NAME)
344 config["timeout"] = "0.500s"
345 config["domain"] = "otherdomain"
346
347 econf = _get_envoy_config(yaml, version="V3")
348 conf = _get_rl_config(econf.as_dict())
349
350 assert conf
351 assert conf.get("typed_config") == config
View as plain text