Merge ~hloeung/content-cache-charm:master into content-cache-charm:master
- Git
- lp:~hloeung/content-cache-charm
- master
- Merge into master
Proposed by
Haw Loeung
Status: | Merged |
---|---|
Approved by: | Haw Loeung |
Approved revision: | 539437892786c3e687ea2f7a9bc999e0fba1c12d |
Merged at revision: | 67f7f1384a4c1f788d2117dc31c377cc29a2051e |
Proposed branch: | ~hloeung/content-cache-charm:master |
Merge into: | content-cache-charm:master |
Prerequisite: | ~hloeung/content-cache-charm:haproxy-config |
Diff against target: |
392 lines (+317/-3) 5 files modified
config.yaml (+6/-0) lib/haproxy.py (+9/-2) reactive/content_cache.py (+6/-1) tests/unit/files/content_cache_rendered_haproxy_test_output_load_balancing_algorithm.txt (+267/-0) tests/unit/test_content_cache.py (+29/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Joel Sing (community) | +1 | Approve | |
Barry Price | Approve | ||
Review via email: mp+390519@code.launchpad.net |
Commit message
Allow overriding default load balancing algorithm used by HAProxy - LP:1891263
Description of the change
To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Revision history for this message
Barry Price (barryprice) wrote : | # |
We could consider adding safety checks to handle a typo or just a plain wrong setting via the haproxy_
On the other hand, if an operator is determined to break things, there's only so much the charms can do to prevent this. Other than that, LGTM - approving on that basis.
review:
Approve
Revision history for this message
Joel Sing (jsing) wrote : | # |
LGTM, minor comments inline.
review:
Approve
(+1)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Change successfully merged at revision 67f7f1384a4c1f7
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/config.yaml b/config.yaml |
2 | index 12560a6..e634fe2 100644 |
3 | --- a/config.yaml |
4 | +++ b/config.yaml |
5 | @@ -45,6 +45,12 @@ options: |
6 | description: > |
7 | Tune HAProxy's hard-stop-after to prevent lingering HAProxy processes |
8 | (LP:1874386). |
9 | + haproxy_load_balancing_algorithm: |
10 | + default: "leastconn" |
11 | + type: string |
12 | + description: > |
13 | + Change the load balancing algorithm used by HAProxy for the |
14 | + backends. |
15 | haproxy_processes: |
16 | default: 0 |
17 | type: int |
18 | diff --git a/lib/haproxy.py b/lib/haproxy.py |
19 | index c3f3a76..cdb5721 100644 |
20 | --- a/lib/haproxy.py |
21 | +++ b/lib/haproxy.py |
22 | @@ -11,15 +11,21 @@ from lib import utils |
23 | |
24 | |
25 | HAPROXY_BASE_PATH = '/etc/haproxy' |
26 | +HAPROXY_LOAD_BALANCING_ALGORITHM = 'leastconn' |
27 | INDENT = ' ' * 4 |
28 | TLS_CIPHER_SUITES = 'ECDHE+AESGCM:ECDHE+AES256:ECDHE+AES128:!SSLv3:!TLSv1' |
29 | |
30 | |
31 | class HAProxyConf: |
32 | - def __init__(self, conf_path=HAPROXY_BASE_PATH, max_connections=0, hard_stop_after='5m'): |
33 | + def __init__( |
34 | + self, conf_path=HAPROXY_BASE_PATH, max_connections=0, hard_stop_after='5m', load_balancing_algorithm=None |
35 | + ): |
36 | self._conf_path = conf_path |
37 | self.max_connections = int(max_connections) |
38 | self.hard_stop_after = hard_stop_after |
39 | + self.load_balancing_algorithm = HAPROXY_LOAD_BALANCING_ALGORITHM |
40 | + if load_balancing_algorithm: |
41 | + self.load_balancing_algorithm = load_balancing_algorithm |
42 | |
43 | @property |
44 | def conf_path(self): |
45 | @@ -212,7 +218,7 @@ listen {name} |
46 | backend backend-{name} |
47 | {options}{indent}{httpchk} |
48 | {indent}http-request set-header Host {site_name} |
49 | -{indent}balance leastconn |
50 | +{indent}balance {load_balancing_algorithm} |
51 | {backends} |
52 | """ |
53 | rendered_output = [] |
54 | @@ -293,6 +299,7 @@ backend backend-{name} |
55 | site=site, |
56 | site_name=site_name, |
57 | httpchk=httpchk, |
58 | + load_balancing_algorithm=self.load_balancing_algorithm, |
59 | backends='\n'.join(backend_confs), |
60 | options=options, |
61 | indent=INDENT, |
62 | diff --git a/reactive/content_cache.py b/reactive/content_cache.py |
63 | index 5b15f8a..5d4460b 100644 |
64 | --- a/reactive/content_cache.py |
65 | +++ b/reactive/content_cache.py |
66 | @@ -208,7 +208,12 @@ def configure_haproxy(): # NOQA: C901 LP#1825084 |
67 | |
68 | max_connections = config.get('max_connections', 0) |
69 | hard_stop_after = config.get('haproxy_hard_stop_after') |
70 | - haproxy = HAProxy.HAProxyConf(max_connections=max_connections, hard_stop_after=hard_stop_after) |
71 | + load_balancing_algorithm = config.get('haproxy_load_balancing_algorithm') |
72 | + haproxy = HAProxy.HAProxyConf( |
73 | + max_connections=max_connections, |
74 | + hard_stop_after=hard_stop_after, |
75 | + load_balancing_algorithm=load_balancing_algorithm, |
76 | + ) |
77 | sites_secrets = secrets_from_config(config.get('sites_secrets')) |
78 | blacklist_ports = [int(x.strip()) for x in config.get('blacklist_ports', '').split(',') if x.strip()] |
79 | sites = sites_from_config(config.get('sites'), sites_secrets, blacklist_ports=blacklist_ports) |
80 | diff --git a/tests/unit/files/content_cache_rendered_haproxy_test_output_load_balancing_algorithm.txt b/tests/unit/files/content_cache_rendered_haproxy_test_output_load_balancing_algorithm.txt |
81 | new file mode 100644 |
82 | index 0000000..b0c6370 |
83 | --- /dev/null |
84 | +++ b/tests/unit/files/content_cache_rendered_haproxy_test_output_load_balancing_algorithm.txt |
85 | @@ -0,0 +1,267 @@ |
86 | +global |
87 | + nbthread 4 |
88 | + maxconn 106496 |
89 | + log /dev/log local0 |
90 | + log /dev/log local1 notice |
91 | + chroot /var/lib/haproxy |
92 | + stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners |
93 | + stats timeout 30s |
94 | + user haproxy |
95 | + group haproxy |
96 | + daemon |
97 | + |
98 | + # LP#1874386: Work around lingering HAProxy processes as per LP:1874386 |
99 | + # and kill them off. |
100 | + hard-stop-after 15m |
101 | + |
102 | + # Default SSL material locations |
103 | + ca-base /etc/ssl/certs |
104 | + crt-base /etc/ssl/private |
105 | + |
106 | + # Default ciphers to use on SSL-enabled listening sockets. |
107 | + # For more information, see ciphers(1SSL). This list is from: |
108 | + # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ |
109 | + # An alternative list with additional directives can be obtained from |
110 | + # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy |
111 | + ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+AES256:ECDHE+AES128:!SSLv3:!TLSv1 |
112 | + ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 |
113 | + # We'll eventually disable DHE (LP#1825321), but for now, bump DH params |
114 | + tune.ssl.default-dh-param 2048 |
115 | + |
116 | + # Increase the SSL/TLS session cache from the default 20k. But |
117 | + # rather than hardcode values, let's just set it to match |
118 | + # global_max_connections (which by default is calculated using |
119 | + # num. of CPU cores and num. of configured sites). Each entry |
120 | + # requires ~200 bytes so on a host with say 32 CPUs, 10 sites, |
121 | + # each with 2000 max conns will only consume around 122 Mbytes |
122 | + # (32 * 10 * 2000 * 200), which is not much. |
123 | + tune.ssl.cachesize 106496 |
124 | + |
125 | +defaults |
126 | + log global |
127 | + maxconn 8192 |
128 | + mode http |
129 | + option httplog |
130 | + option dontlognull |
131 | + timeout connect 5s |
132 | + timeout client 50s |
133 | + timeout server 50s |
134 | + errorfile 400 /etc/haproxy/errors/400.http |
135 | + errorfile 403 /etc/haproxy/errors/403.http |
136 | + errorfile 408 /etc/haproxy/errors/408.http |
137 | + errorfile 500 /etc/haproxy/errors/500.http |
138 | + errorfile 502 /etc/haproxy/errors/502.http |
139 | + errorfile 503 /etc/haproxy/errors/503.http |
140 | + errorfile 504 /etc/haproxy/errors/504.http |
141 | + |
142 | +resolvers dns |
143 | + nameserver dns1 127.0.0.53:53 |
144 | + resolve_retries 3 |
145 | + timeout resolve 3s |
146 | + timeout retry 3s |
147 | + accepted_payload_size 8192 |
148 | + |
149 | +listen stats |
150 | + bind 127.0.0.1:10000 |
151 | + acl allowed_cidr src 127.0.0.0/8 |
152 | + http-request deny unless allowed_cidr |
153 | + |
154 | + mode http |
155 | + stats enable |
156 | + stats uri / |
157 | + stats realm Haproxy\ Statistics |
158 | + stats auth haproxy:biometricsarenotsecret |
159 | + stats refresh 3 |
160 | + |
161 | + |
162 | +listen combined-80 |
163 | + bind 0.0.0.0:80 |
164 | + bind :::80 |
165 | + redirect scheme https code 301 if { hdr(Host) -i site2.local } !{ ssl_fc } |
166 | + use_backend backend-cached-site1-local if { hdr(Host) -i site1.local } |
167 | + use_backend backend-cached-site3-local if { hdr(Host) -i site3.local } |
168 | + use_backend backend-cached-site4-local if { hdr(Host) -i site4.local } |
169 | + use_backend backend-cached-site5 if { hdr(Host) -i site5.local } |
170 | + use_backend backend-cached-site6-local if { hdr(Host) -i site6.local } |
171 | + use_backend backend-cached-site9-local if { hdr(Host) -i site9.local } |
172 | + default_backend backend-cached-site3-local |
173 | + |
174 | +listen site1-local |
175 | + bind 127.0.0.1:8080 |
176 | + default_backend backend-site1-local |
177 | + |
178 | +listen cached-site2-local |
179 | + bind 0.0.0.0:443 ssl crt /etc/haproxy/site2-bundle.crt alpn h2,http/1.1 |
180 | + bind :::443 ssl crt /etc/haproxy/site2-bundle.crt alpn h2,http/1.1 |
181 | + default_backend backend-cached-site2-local |
182 | + |
183 | +listen site2-local |
184 | + bind 127.0.0.1:8081 |
185 | + default_backend backend-site2-local |
186 | + |
187 | +listen site3-local |
188 | + bind 127.0.0.1:8082 |
189 | + default_backend backend-site3-local |
190 | + |
191 | +listen site5 |
192 | + bind 127.0.0.1:8083 |
193 | + default_backend backend-site5 |
194 | + |
195 | +listen site5-2 |
196 | + bind 127.0.0.1:8084 |
197 | + default_backend backend-site5-2 |
198 | + |
199 | +listen site6-local |
200 | + bind 127.0.0.1:8085 |
201 | + default_backend backend-site6-local |
202 | + |
203 | +listen combined-444 |
204 | + bind 0.0.0.0:444 ssl crt /etc/haproxy/site7-bundle.crt crt /etc/haproxy/site8-bundle.crt alpn h2,http/1.1 |
205 | + bind :::444 ssl crt /etc/haproxy/site7-bundle.crt crt /etc/haproxy/site8-bundle.crt alpn h2,http/1.1 |
206 | + use_backend backend-cached-site7-local if { hdr(Host) -i site7.local } |
207 | + use_backend backend-cached-site8-local if { hdr(Host) -i site8.local } |
208 | + |
209 | +listen site7-local |
210 | + bind 127.0.0.1:8086 |
211 | + default_backend backend-site7-local |
212 | + |
213 | +listen site8-local |
214 | + bind 127.0.0.1:8087 |
215 | + default_backend backend-site8-local |
216 | + |
217 | +listen site8-local-2 |
218 | + bind 127.0.0.1:8088 |
219 | + default_backend backend-site8-local-2 |
220 | + |
221 | +listen site9-local |
222 | + bind 127.0.0.1:8089 |
223 | + default_backend backend-site9-local |
224 | + |
225 | +backend backend-cached-site1-local |
226 | + option forwardfor |
227 | + option httpchk HEAD /?token=1861920000_f3e404e205ed44749e942d481f7a7bec57c5e78a HTTP/1.0\r\nHost:\ site1.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
228 | + http-request set-header Host site1.local |
229 | + balance roundrobin |
230 | + server server_1 127.0.0.1:6080 check inter 2s rise 2 fall 60 maxconn 2048 |
231 | + |
232 | +backend backend-site1-local |
233 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site1.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
234 | + http-request set-header Host site1.local |
235 | + balance roundrobin |
236 | + server server_1 127.0.1.10:80 check inter 5s rise 2 fall 5 maxconn 2048 |
237 | + server server_2 127.0.1.11:80 check inter 5s rise 2 fall 5 maxconn 2048 |
238 | + server server_3 127.0.1.12:80 check inter 5s rise 2 fall 5 maxconn 2048 |
239 | + |
240 | +backend backend-cached-site2-local |
241 | + option forwardfor |
242 | + option httpchk GET /check/ HTTP/1.0\r\nHost:\ site2.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
243 | + http-request set-header Host site2.local |
244 | + balance roundrobin |
245 | + server server_1 127.0.0.1:6081 check inter 2s rise 2 fall 60 maxconn 2048 |
246 | + |
247 | +backend backend-site2-local |
248 | + option httpchk GET /check/ HTTP/1.0\r\nHost:\ site2.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
249 | + http-request set-header Host site2.local |
250 | + balance roundrobin |
251 | + server server_1 127.0.1.10:443 check inter 5s rise 2 fall 5 maxconn 1024 ssl sni str(site2.local) check-sni site2.local verify required ca-file ca-certificates.crt |
252 | + server server_2 127.0.1.11:443 check inter 5s rise 2 fall 5 maxconn 1024 ssl sni str(site2.local) check-sni site2.local verify required ca-file ca-certificates.crt |
253 | + server server_3 127.0.1.12:443 check inter 5s rise 2 fall 5 maxconn 1024 ssl sni str(site2.local) check-sni site2.local verify required ca-file ca-certificates.crt |
254 | + |
255 | +backend backend-cached-site3-local |
256 | + option forwardfor |
257 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site3.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
258 | + http-request set-header Host site3.local |
259 | + balance roundrobin |
260 | + server server_1 127.0.0.1:6082 check inter 2s rise 2 fall 60 maxconn 4096 |
261 | + |
262 | +backend backend-site3-local |
263 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site3.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
264 | + http-request set-header Host site3.local |
265 | + balance roundrobin |
266 | + server server_1 127.0.1.10:80 check inter 5s rise 2 fall 5 maxconn 2048 |
267 | + server server_2 127.0.1.11:80 check inter 5s rise 2 fall 5 maxconn 2048 |
268 | + server server_3 127.0.1.12:80 check inter 5s rise 2 fall 5 maxconn 2048 |
269 | + |
270 | +backend backend-cached-site4-local |
271 | + option forwardfor |
272 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site4.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
273 | + http-request set-header Host site4.local |
274 | + balance roundrobin |
275 | + server server_1 127.0.0.1:6083 check inter 2s rise 2 fall 60 maxconn 2048 |
276 | + |
277 | +backend backend-cached-site5 |
278 | + option forwardfor |
279 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site5.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
280 | + http-request set-header Host site5.local |
281 | + balance roundrobin |
282 | + server server_1 127.0.0.1:6084 check inter 2s rise 2 fall 60 maxconn 2048 |
283 | + |
284 | +backend backend-site5 |
285 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site5.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
286 | + http-request set-header Host site5.local |
287 | + balance roundrobin |
288 | + server server_1 127.0.1.10:80 check inter 5s rise 2 fall 5 maxconn 2048 |
289 | + |
290 | +backend backend-site5-2 |
291 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site5.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
292 | + http-request set-header Host site5.local |
293 | + balance roundrobin |
294 | + server server_1 127.0.1.11:80 check inter 5s rise 2 fall 5 maxconn 2048 |
295 | + |
296 | +backend backend-cached-site6-local |
297 | + option forwardfor |
298 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site6.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
299 | + http-request set-header Host site6.local |
300 | + balance roundrobin |
301 | + server server_1 127.0.0.1:6085 check inter 2s rise 2 fall 60 maxconn 2048 |
302 | + |
303 | +backend backend-site6-local |
304 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site6.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
305 | + http-request set-header Host site6.local |
306 | + balance roundrobin |
307 | + server server_1 127.0.1.10:443 check inter 5s rise 2 fall 5 maxconn 2048 ssl sni str(site6.local) check-sni site6.local verify required ca-file ca-certificates.crt |
308 | + |
309 | +backend backend-cached-site7-local |
310 | + option forwardfor |
311 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site7.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
312 | + http-request set-header Host site7.local |
313 | + balance roundrobin |
314 | + server server_1 127.0.0.1:6086 check inter 2s rise 2 fall 60 maxconn 2048 |
315 | + |
316 | +backend backend-site7-local |
317 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site7.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
318 | + http-request set-header Host site7.local |
319 | + balance roundrobin |
320 | + server server_1 127.0.1.10:80 check inter 5s rise 2 fall 5 maxconn 2048 |
321 | + |
322 | +backend backend-cached-site8-local |
323 | + option forwardfor |
324 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site8.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
325 | + http-request set-header Host site8.local |
326 | + balance roundrobin |
327 | + server server_1 127.0.0.1:6087 check inter 2s rise 2 fall 60 maxconn 2048 |
328 | + |
329 | +backend backend-site8-local |
330 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site8.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
331 | + http-request set-header Host site8.local |
332 | + balance roundrobin |
333 | + server server_1 127.0.1.10:80 check inter 5s rise 2 fall 5 maxconn 2048 |
334 | + |
335 | +backend backend-site8-local-2 |
336 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ auth.site8.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
337 | + http-request set-header Host auth.site8.local |
338 | + balance roundrobin |
339 | + server server_1 127.0.1.10:443 check inter 5s rise 2 fall 5 maxconn 2048 ssl sni str(auth.site8.local) check-sni auth.site8.local verify required ca-file ca-certificates.crt |
340 | + |
341 | +backend backend-cached-site9-local |
342 | + option forwardfor |
343 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site9.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
344 | + http-request set-header Host site9.local |
345 | + balance roundrobin |
346 | + server server_1 127.0.0.1:6088 check inter 2s rise 2 fall 60 maxconn 2048 |
347 | + |
348 | +backend backend-site9-local |
349 | + option httpchk HEAD / HTTP/1.0\r\nHost:\ site9.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache |
350 | + http-request set-header Host site9.local |
351 | + balance roundrobin |
352 | + server server_1 127.0.1.15:80 check inter 1m rise 2 fall 5 maxconn 2048 |
353 | diff --git a/tests/unit/test_content_cache.py b/tests/unit/test_content_cache.py |
354 | index 3b62cbb..561cd53 100644 |
355 | --- a/tests/unit/test_content_cache.py |
356 | +++ b/tests/unit/test_content_cache.py |
357 | @@ -485,6 +485,35 @@ site1.local: |
358 | @freezegun.freeze_time("2019-03-22", tz_offset=0) |
359 | @mock.patch('charmhelpers.core.hookenv.opened_ports') |
360 | @mock.patch('charms.reactive.set_flag') |
361 | + @mock.patch('reactive.content_cache.update_logrotate') |
362 | + def test_configure_haproxy_sites_load_balancing_algorithm(self, logrotation, set_flag, opened_ports): |
363 | + with open('tests/unit/files/config_test_config.txt', 'r', encoding='utf-8') as f: |
364 | + config = f.read() |
365 | + self.mock_config.return_value = { |
366 | + 'haproxy_hard_stop_after': '15m', |
367 | + 'haproxy_load_balancing_algorithm': 'roundrobin', |
368 | + 'max_connections': 8192, |
369 | + 'sites': config, |
370 | + } |
371 | + |
372 | + with mock.patch('lib.haproxy.HAProxyConf.conf_file', new_callable=mock.PropertyMock) as mock_conf_file: |
373 | + mock_conf_file.return_value = os.path.join(self.tmpdir, 'haproxy.cfg') |
374 | + opened_ports.return_value = ['443/tcp'] |
375 | + content_cache.configure_haproxy() |
376 | + |
377 | + with open( |
378 | + 'tests/unit/files/content_cache_rendered_haproxy_test_output_load_balancing_algorithm.txt', |
379 | + 'r', |
380 | + encoding='utf-8', |
381 | + ) as f: |
382 | + want = f.read() |
383 | + with open(os.path.join(self.tmpdir, 'haproxy.cfg'), 'r', encoding='utf-8') as f: |
384 | + got = f.read() |
385 | + self.assertEqual(got, want) |
386 | + |
387 | + @freezegun.freeze_time("2019-03-22", tz_offset=0) |
388 | + @mock.patch('charmhelpers.core.hookenv.opened_ports') |
389 | + @mock.patch('charms.reactive.set_flag') |
390 | @mock.patch('lib.utils.package_version') |
391 | @mock.patch('reactive.content_cache.update_logrotate') |
392 | def test_configure_haproxy_processes_and_threads(self, logrotation, package_version, set_flag, opened_ports): |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.