Merge ~hloeung/content-cache-charm:haproxy-config into content-cache-charm:master

Proposed by Haw Loeung
Status: Merged
Approved by: Haw Loeung
Approved revision: 6cd07c6673b5c565b0b0d9757aa07f27be2872d4
Merged at revision: 1c438f4b91fe77b3e2826a5c4efc5b2a03d35b60
Proposed branch: ~hloeung/content-cache-charm:haproxy-config
Merge into: content-cache-charm:master
Diff against target: 171 lines (+132/-3)
3 files modified
lib/haproxy.py (+10/-3)
tests/unit/files/content_cache_rendered_haproxy_test_output_srv_template.txt (+99/-0)
tests/unit/test_content_cache.py (+23/-0)
Reviewer Review Type Date Requested Status
Barry Price Approve
Canonical IS Reviewers Pending
Review via email: mp+392268@code.launchpad.net

Commit message

Added support for DNS SRV / server templates - LP:1871256

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Barry Price (barryprice) wrote :

I wasn't familiar with haproxy's SRV support, consider adding a comment (or comments) linking to the docs. I think we'd want to explicitly explain that in config.yaml too.

Otherwise LGTM

review: Approve
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 1c438f4b91fe77b3e2826a5c4efc5b2a03d35b60

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/haproxy.py b/lib/haproxy.py
2index 09a7809..a2b9419 100644
3--- a/lib/haproxy.py
4+++ b/lib/haproxy.py
5@@ -261,17 +261,24 @@ backend backend-{name}
6
7 backend_confs = []
8 count = 0
9- for backend in loc_conf.get('backends'):
10+ for backend_flags in loc_conf.get('backends'):
11+ flags = backend_flags.split()
12+ backend = flags.pop(0)
13+
14 count += 1
15+ name = 'server server_{}'.format(count)
16+
17+ for flag in flags:
18+ if flag == 'srv':
19+ name = 'server-template server_ {}'.format(flags[flags.index(flag) + 1])
20
21- name = 'server_{}'.format(count)
22 use_resolvers = ''
23 try:
24 utils.ip_addr_port_split(backend)
25 except utils.InvalidAddressPortError:
26 use_resolvers = ' resolvers dns init-addr none'
27 backend_confs.append(
28- '{indent}server {name} {backend}{use_resolvers} check inter {inter_time} '
29+ '{indent}{name} {backend}{use_resolvers} check inter {inter_time} '
30 'rise {rise_count} fall {fall_count} maxconn {maxconn}{tls}'.format(
31 name=name,
32 backend=backend,
33diff --git a/tests/unit/files/content_cache_rendered_haproxy_test_output_srv_template.txt b/tests/unit/files/content_cache_rendered_haproxy_test_output_srv_template.txt
34new file mode 100644
35index 0000000..8c24f8d
36--- /dev/null
37+++ b/tests/unit/files/content_cache_rendered_haproxy_test_output_srv_template.txt
38@@ -0,0 +1,99 @@
39+global
40+ nbthread 4
41+ maxconn 16384
42+ log /dev/log local0
43+ log /dev/log local1 notice
44+ chroot /var/lib/haproxy
45+ stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
46+ stats timeout 30s
47+ server-state-file /run/haproxy/saved-server-state
48+ user haproxy
49+ group haproxy
50+ daemon
51+
52+ # LP#1874386: Work around lingering HAProxy processes as per LP:1874386
53+ # and kill them off.
54+ hard-stop-after 15m
55+
56+ # Default SSL material locations
57+ ca-base /etc/ssl/certs
58+ crt-base /etc/ssl/private
59+
60+ # Default ciphers to use on SSL-enabled listening sockets.
61+ # For more information, see ciphers(1SSL). This list is from:
62+ # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
63+ # An alternative list with additional directives can be obtained from
64+ # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
65+ ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+AES256:ECDHE+AES128:!SSLv3:!TLSv1
66+ ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
67+ # We'll eventually disable DHE (LP#1825321), but for now, bump DH params
68+ tune.ssl.default-dh-param 2048
69+
70+ # Increase the SSL/TLS session cache from the default 20k. But
71+ # rather than hardcode values, let's just set it to match
72+ # global_max_connections (which by default is calculated using
73+ # num. of CPU cores and num. of configured sites). Each entry
74+ # requires ~200 bytes so on a host with say 32 CPUs, 10 sites,
75+ # each with 2000 max conns will only consume around 122 Mbytes
76+ # (32 * 10 * 2000 * 200), which is not much.
77+ tune.ssl.cachesize 16384
78+
79+defaults
80+ log global
81+ maxconn 8192
82+ mode http
83+ option httplog
84+ option dontlognull
85+ timeout connect 5s
86+ timeout client 50s
87+ timeout server 50s
88+ errorfile 400 /etc/haproxy/errors/400.http
89+ errorfile 403 /etc/haproxy/errors/403.http
90+ errorfile 408 /etc/haproxy/errors/408.http
91+ errorfile 500 /etc/haproxy/errors/500.http
92+ errorfile 502 /etc/haproxy/errors/502.http
93+ errorfile 503 /etc/haproxy/errors/503.http
94+ errorfile 504 /etc/haproxy/errors/504.http
95+ load-server-state-from-file global
96+
97+resolvers dns
98+ nameserver dns1 127.0.0.53:53
99+ resolve_retries 3
100+ timeout resolve 3s
101+ timeout retry 3s
102+ accepted_payload_size 8192
103+
104+listen stats
105+ bind 127.0.0.1:10000
106+ acl allowed_cidr src 127.0.0.0/8
107+ http-request deny unless allowed_cidr
108+
109+ mode http
110+ stats enable
111+ stats uri /
112+ stats realm Haproxy\ Statistics
113+ stats auth haproxy:biometricsarenotsecret
114+ stats refresh 3
115+
116+
117+listen cached-site1-local
118+ bind 0.0.0.0:80
119+ bind :::80
120+ default_backend backend-cached-site1-local
121+
122+listen site1-local
123+ bind 127.0.0.1:8080
124+ default_backend backend-site1-local
125+
126+backend backend-cached-site1-local
127+ option forwardfor
128+ option httpchk HEAD / HTTP/1.0\r\nHost:\ site1.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache
129+ http-request set-header Host site1.local
130+ balance leastconn
131+ server server_1 127.0.0.1:6080 check inter 2s rise 2 fall 60 maxconn 2048
132+
133+backend backend-site1-local
134+ option httpchk HEAD / HTTP/1.0\r\nHost:\ site1.local\r\nUser-Agent:\ haproxy/httpchk\r\nCache-Control:\ no-cache
135+ http-request set-header Host site1.local
136+ balance leastconn
137+ server-template server_ 4 _http._tcp.uk.archive.ubuntu.com:80 resolvers dns init-addr none check inter 5s rise 2 fall 5 maxconn 2048
138diff --git a/tests/unit/test_content_cache.py b/tests/unit/test_content_cache.py
139index d0c6cd5..34a5f2c 100644
140--- a/tests/unit/test_content_cache.py
141+++ b/tests/unit/test_content_cache.py
142@@ -467,6 +467,29 @@ site1.local:
143 @mock.patch('charms.reactive.set_flag')
144 @mock.patch('lib.haproxy.HAProxyConf.save_server_state')
145 @mock.patch('reactive.content_cache.update_logrotate')
146+ def test_configure_haproxy_sites_srv(self, logrotation, save_s_state, set_flag, opened_ports):
147+ config = '''
148+site1.local:
149+ locations:
150+ /:
151+ backends: ['_http._tcp.uk.archive.ubuntu.com:80 srv 4']
152+'''
153+ self.mock_config.return_value = {'haproxy_hard_stop_after': '15m', 'max_connections': 8192, 'sites': config}
154+ with mock.patch('lib.haproxy.HAProxyConf.conf_file', new_callable=mock.PropertyMock) as mock_conf_file:
155+ mock_conf_file.return_value = os.path.join(self.tmpdir, 'haproxy.cfg')
156+ content_cache.configure_haproxy()
157+
158+ with open('tests/unit/files/content_cache_rendered_haproxy_test_output_srv_template.txt', 'r', encoding='utf-8') as f:
159+ want = f.read()
160+ with open(os.path.join(self.tmpdir, 'haproxy.cfg'), 'r', encoding='utf-8') as f:
161+ got = f.read()
162+ self.assertEqual(got, want)
163+
164+ @freezegun.freeze_time("2019-03-22", tz_offset=0)
165+ @mock.patch('charmhelpers.core.hookenv.opened_ports')
166+ @mock.patch('charms.reactive.set_flag')
167+ @mock.patch('lib.haproxy.HAProxyConf.save_server_state')
168+ @mock.patch('reactive.content_cache.update_logrotate')
169 def test_configure_haproxy_sites_auto_maxconns(self, logrotation, save_s_state, set_flag, opened_ports):
170 with open('tests/unit/files/config_test_config.txt', 'r', encoding='utf-8') as f:
171 config = f.read()

Subscribers

People subscribed via source and target branches