userver: en/testsuite/databases/redis/genredis.py Source File
Loading...
Searching...
No Matches
genredis.py
1import argparse
2import pathlib
3import string
4
5MASTER_TPL_FILENAME = 'redis_master.conf.tpl'
6SENTINEL_TPL_FILENAME = 'redis_sentinel.conf.tpl'
7SLAVE_TPL_FILENAME = 'redis_slave.conf.tpl'
8CLUSTER_TPL_FILENAME = 'redis_cluster_node.conf.tpl'
9
10SENTINEL_PARAMS = [
11 {
12 'down_after_milliseconds': 60000,
13 'failover_timeout': 180000,
14 'parallel_syncs': 1,
15 },
16 {
17 'down_after_milliseconds': 10000,
18 'failover_timeout': 180000,
19 'parallel_syncs': 5,
20 },
21]
22
23
24def _parse_args():
25 parser = argparse.ArgumentParser()
26 parser.add_argument(
27 '--output',
28 help='Path to output directory',
29 type=pathlib.Path,
30 )
31 parser.add_argument(
32 '--host',
33 type=int,
34 default='localhost',
35 help='Redis host for sentinel config',
36 )
37 parser.add_argument(
38 '--master0-port',
39 type=int,
40 default=16379,
41 help='Redis masters0 port',
42 )
43 parser.add_argument(
44 '--master1-port',
45 type=int,
46 default=16389,
47 help='Redis masters0 port',
48 )
49 parser.add_argument(
50 '--slave0-ports',
51 type=int,
52 default=16380,
53 help='Redis slave0 port',
54 )
55 parser.add_argument(
56 '--slave1-ports',
57 type=int,
58 default=16390,
59 help='Redis slave1 port',
60 )
61 parser.add_argument(
62 '--slave2-ports',
63 type=int,
64 default=16381,
65 help='Redis slave2 port',
66 )
67 parser.add_argument(
68 '--sentinel-port',
69 type=int,
70 default=26379,
71 help='Redis sentinel port',
72 )
73 parser.add_argument(
74 '--cluster-port',
75 type=int,
76 nargs='+',
77 default=[17380, 17381, 17382, 17383, 17384, 17385],
78 help='Redis cluster port',
79 )
80 return parser.parse_args()
81
82
83def _generate_redis_config(
84 input_file: pathlib.Path,
85 output_file: pathlib.Path,
86 host: str,
87 port: int,
88 master_port: int | None = None,
89) -> None:
90 config_tpl = input_file.read_text()
91 config_body = string.Template(config_tpl).substitute(
92 host=host,
93 port=port,
94 master_port=master_port,
95 )
96 output_file.write_text(config_body)
97
98
99def _generate_master(
100 host: str,
101 port: int,
102 output_path: pathlib.Path,
103 index: int,
104) -> None:
105 input_file = _redis_config_directory() / MASTER_TPL_FILENAME
106 output_file = _construct_output_filename(
107 output_path,
108 MASTER_TPL_FILENAME,
109 index,
110 )
111 _generate_redis_config(
112 input_file,
113 output_file,
114 host,
115 port,
116 )
117
118
119def _generate_slave(
120 host: str,
121 port: int,
122 master_port: int,
123 output_path: pathlib.Path,
124 index: int,
125) -> None:
126 input_file = _redis_config_directory() / SLAVE_TPL_FILENAME
127 output_file = _construct_output_filename(
128 output_path,
129 SLAVE_TPL_FILENAME,
130 index,
131 )
132 _generate_redis_config(
133 input_file,
134 output_file,
135 host,
136 port,
137 master_port,
138 )
139
140
141def _generate_sentinel(
142 host: str,
143 sentinel_port: int,
144 ports: list[int],
145 output_path: pathlib.Path,
146 params: list,
147) -> None:
148 input_file = _redis_config_directory() / SENTINEL_TPL_FILENAME
149 lines = ['daemonize yes', 'port %d' % sentinel_port, '']
150 config_tpl = input_file.read_text()
151
152 for index, (port, param) in enumerate(zip(ports, params)):
153 config_body = string.Template(config_tpl).substitute(
154 index=index,
155 host=host,
156 port=port,
157 **param,
158 )
159 lines.append(config_body)
160
161 output_path.joinpath('redis_sentinel.conf').write_text('\n'.join(lines))
162
163
164def _generate_cluster_node(
165 host: str,
166 port: int,
167 output_path: pathlib.Path,
168 index: int,
169) -> None:
170 input_file = _redis_config_directory() / CLUSTER_TPL_FILENAME
171 output_file = _construct_output_filename(
172 output_path,
173 CLUSTER_TPL_FILENAME,
174 index,
175 )
176
177 _generate_redis_config(
178 input_file,
179 output_file,
180 host,
181 port,
182 )
183
184
185def _construct_output_filename(
186 output_path: pathlib.Path,
187 tpl_filename: str,
188 number: int,
189) -> pathlib.Path:
190 name = tpl_filename.split('.', 1)[0]
191 config_filename = ''.join((name, str(number), '.conf'))
192 return output_path / config_filename
193
194
195def _redis_config_directory() -> pathlib.Path:
196 return pathlib.Path(__file__).parent / 'configs'
197
198
199def generate_cluster_redis_configs(
200 output_path: pathlib.Path,
201 host: str,
202 cluster_ports: tuple[int, ...],
203) -> None:
204 _generate_cluster_node(
205 host,
206 6379,
207 output_path,
208 0,
209 )
210
211
212def generate_standalone_redis_config(
213 output_path: pathlib.Path,
214 host: str,
215 port: int,
216) -> None:
217 input_file = _redis_config_directory() / MASTER_TPL_FILENAME
218 output_file = output_path / 'test_standalone_master0.conf'
219
220 _generate_redis_config(
221 input_file,
222 output_file,
223 host,
224 port,
225 )
226
227
228def generate_redis_configs(
229 output_path: pathlib.Path,
230 host: str,
231 master0_port: int,
232 master1_port: int,
233 slave0_port: int,
234 slave1_port: int,
235 slave2_port: int,
236 sentinel_port: int,
237) -> None:
238 _generate_master(host, master0_port, output_path, 0)
239 _generate_master(host, master1_port, output_path, 1)
240
241 _generate_slave(
242 host,
243 slave0_port,
244 master0_port,
245 output_path,
246 0,
247 )
248 _generate_slave(
249 host,
250 slave1_port,
251 master1_port,
252 output_path,
253 1,
254 )
255 _generate_slave(
256 host,
257 slave2_port,
258 master0_port,
259 output_path,
260 2,
261 )
262
263 _generate_sentinel(
264 host,
265 sentinel_port,
266 [master0_port, master1_port],
267 output_path,
268 SENTINEL_PARAMS,
269 )
270
271
272def main():
273 args = _parse_args()
274 generate_redis_configs(
275 output_path=args.output,
276 host=args.host,
277 master0_port=args.master0_port,
278 master1_port=args.master1_port,
279 slave0_port=args.slave0_port,
280 slave1_port=args.slave1_port,
281 slave2_port=args.slave2_port,
282 sentinel_port=args.sentinel_port,
283 )
284 generate_cluster_redis_configs(
285 output_path=args.output,
286 host=args.host,
287 cluster_ports=args.cluster_port,
288 )
289
290
291if __name__ == '__main__':
292 main()