3 Parses /etc/keepalived/keepalived.conf
5 Author: Raphael Pinson <raphink@gmail.com>
8 This lens tries to keep as close as possible to `man 5 keepalived.conf` where possible.
11 This file is licenced under the LGPL v2+, like the rest of Augeas.
16 About: Configuration files
17 This lens applies to /etc/keepalived/keepalived.conf. See <filter>.
20 The <Test_Keepalived> file contains various examples and tests.
27 (************************************************************************
28 * Group: USEFUL PRIMITIVES
29 *************************************************************************)
31 (* Group: Comments and empty lines *)
34 let indent = Util.indent
40 let opt_eol = del /[ \t]*\n?/ " "
43 let sep_spc = Sep.space
46 Map comments in "#comment" nodes *)
47 let comment = Util.comment_generic /[ \t]*[#!][ \t]*/ "# "
50 Map comments at eol *)
51 let comment_eol = Util.comment_generic /[ \t]*[#!][ \t]*/ " # "
53 (* View: comment_or_eol
54 A <comment_eol> or <eol> *)
55 let comment_or_eol = comment_eol | (del /[ \t]*[#!]?\n/ "\n")
59 let empty = Util.empty
61 (* View: sto_email_addr *)
62 let sto_email_addr = store Rx.email_addr
67 (* Variable: word_slash *)
68 let word_slash = word | "/"
71 let sto_word = store word
74 let sto_num = store Rx.relinteger
76 (* View: sto_to_eol *)
77 let sto_to_eol = store /[^#! \t\n][^#!\n]*[^#! \t\n]|[^#! \t\n]/
80 let field (kw:regexp) (sto:lens) = indent . Build.key_value_line_comment kw sep_spc sto comment_eol
84 let flag (kw:regexp) = [ indent . key kw . comment_or_eol ]
87 An IP <space> port pair *)
88 let ip_port = [ label "ip" . sto_word ] . sep_spc . [ label "port" . sto_num ]
91 A generic block with a title lens.
92 The definition is very similar to Build.block_newlines
93 but uses a different type of <comment>. *)
94 let lens_block (title:lens) (sto:lens) =
96 . Build.block_newlines sto comment . eol ]
99 A simple block with just a block title *)
100 let block (kw:regexp) (sto:lens) = lens_block (key kw) sto
103 A block with a block title and name *)
104 let named_block (kw:string) (sto:lens) = lens_block (key kw . sep_spc . sto_word) sto
106 (* View: named_block_arg_title
107 A title lens for named_block_arg *)
108 let named_block_arg_title (kw:string) (name:string) (arg:string) =
110 . [ label name . sto_word ]
112 . [ label arg . sto_word ]
114 (* View: named_block_arg
115 A block with a block title, a name and an argument *)
116 let named_block_arg (kw:string) (name:string) (arg:string) (sto:lens) =
117 lens_block (named_block_arg_title kw name arg) sto
120 (************************************************************************
121 * Group: GLOBAL CONFIGURATION
122 *************************************************************************)
125 A simple email address entry *)
126 let email = [ indent . label "email" . sto_email_addr . comment_or_eol ]
128 (* View: global_defs_field
129 Possible fields in the global_defs block *)
130 let global_defs_field =
131 let word_re = "smtp_server"|"lvs_id"|"router_id"
132 in let num_re = "smtp_connect_timeout"
133 in block "notification_email" email
134 | field "notification_email_from" sto_email_addr
135 | field word_re sto_word
136 | field num_re sto_num
139 A global_defs block *)
140 let global_defs = block "global_defs" global_defs_field
143 A prefix for IP addresses *)
144 let prefixlen = [ label "prefixlen" . Util.del_str "/" . sto_num ]
147 An IP address or range with an optional mask *)
148 let ipaddr = label "ipaddr" . store /[0-9.-]+/ . prefixlen?
151 A device for IP addresses *)
152 let ipdev = [ key "dev" . sep_spc . sto_word ]
154 (* View: static_ipaddress_field
155 The whole string is fed to ip addr add.
156 You can truncate the string anywhere you like and let ip addr add use defaults for the rest of the string.
157 To be refined with fields according to `ip addr help`.
159 let static_ipaddress_field = [ indent . ipaddr
163 (* View: static_routes_field
164 src $SRC_IP to $DST_IP dev $SRC_DEVICE
166 let static_routes_field = [ indent . label "route"
167 . [ key "src" . sto_word ] . sep_spc
168 . [ key "to" . sto_word ] . sep_spc
169 . [ key "dev" . sto_word ] . comment_or_eol ]
171 (* View: static_routes *)
172 let static_routes = block "static_ipaddress" static_ipaddress_field
173 | block "static_routes" static_routes_field
177 A global configuration entry *)
178 let global_conf = global_defs | static_routes
181 (************************************************************************
182 * Group: VRRP CONFIGURATION
183 *************************************************************************)
185 (*View: vrrp_sync_group_field *)
186 let vrrp_sync_group_field = block "group" [ indent . key word . comment_or_eol ]
188 (* View: vrrp_sync_group *)
189 let vrrp_sync_group = named_block "vrrp_sync_group" vrrp_sync_group_field
191 (* View: vrrp_instance_field *)
192 let vrrp_instance_field =
193 let word_re = "state" | "interface" | "lvs_sync_daemon_interface"
194 in let num_re = "virtual_router_id" | "priority" | "advert_int" | "garp_master_delay"
195 in let to_eol_re = /notify_(master|backup|fault)/
196 in let flag_re = "smtp_alert" | "nopreempt" | "ha_suspend" | "debug"
197 in field word_re sto_word
198 | field num_re sto_num
199 | field to_eol_re sto_to_eol
201 | block "authentication" (
202 field /auth_(type|pass)/ sto_word
204 | block "virtual_ipaddress" static_ipaddress_field
205 | block /track_(interface|script)/ ( flag word )
207 (* View: vrrp_instance *)
208 let vrrp_instance = named_block "vrrp_instance" vrrp_instance_field
210 (* View: vrrp_script_field *)
211 let vrrp_script_field =
212 let num_re = "interval" | "weight"
213 in let to_eol_re = "script"
214 in field to_eol_re sto_to_eol
215 | field num_re sto_num
217 (* View: vrrp_script *)
218 let vrrp_script = named_block "vrrp_script" vrrp_script_field
222 contains subblocks of VRRP synchronization group(s) and VRRP instance(s) *)
223 let vrrpd_conf = vrrp_sync_group | vrrp_instance | vrrp_script
226 (************************************************************************
227 * Group: REAL SERVER CHECKS CONFIGURATION
228 *************************************************************************)
230 (* View: tcp_check_field *)
231 let tcp_check_field =
232 let word_re = "bindto"
233 in let num_re = /connect_(timeout|port)/
234 in field word_re sto_word
235 | field num_re sto_num
237 (* View: misc_check_field *)
238 let misc_check_field =
239 let flag_re = "misc_dynamic"
240 in let num_re = "misc_timeout"
241 in let to_eol_re = "misc_path"
242 in field num_re sto_num
244 | field to_eol_re sto_to_eol
246 (* View: smtp_host_check_field *)
247 let smtp_host_check_field =
248 let word_re = "connect_ip" | "bindto"
249 in let num_re = "connect_port"
250 in field word_re sto_word
251 | field num_re sto_num
253 (* View: smtp_check_field *)
254 let smtp_check_field =
255 let word_re = "connect_ip" | "bindto"
256 in let num_re = "connect_timeout" | "retry" | "delay_before_retry"
257 in let to_eol_re = "helo_name"
258 in field word_re sto_word
259 | field num_re sto_num
260 | field to_eol_re sto_to_eol
261 | block "host" smtp_host_check_field
263 (* View: http_url_check_field *)
264 let http_url_check_field =
265 let word_re = "digest"
266 in let num_re = "status_code"
267 in let to_eol_re = "path"
268 in field word_re sto_word
269 | field num_re sto_num
270 | field to_eol_re sto_to_eol
272 (* View: http_check_field *)
273 let http_check_field =
274 let num_re = /connect_(timeout|port)/ | "nb_get_retry" | "delay_before_retry"
275 in field num_re sto_num
276 | block "url" http_url_check_field
278 (* View: real_server_field *)
279 let real_server_field =
280 let num_re = "weight"
281 in let flag_re = "inhibit_on_failure"
282 in let to_eol_re = /notify_(up|down)/
283 in field num_re sto_num
285 | field to_eol_re sto_to_eol
286 | block "TCP_CHECK" tcp_check_field
287 | block "MISC_CHECK" misc_check_field
288 | block "SMTP_CHECK" smtp_check_field
289 | block /(HTTP|SSL)_GET/ http_check_field
291 (************************************************************************
292 * Group: LVS CONFIGURATION
293 *************************************************************************)
295 (* View: virtual_server_field *)
296 let virtual_server_field =
297 let num_re = "delay_loop" | "persistence_timeout" | "quorum" | "hysteresis"
298 in let word_re = /lb_(algo|kind)/ | "nat_mask" | "protocol" | "persistence_granularity"
300 in let flag_re = "ops" | "ha_suspend" | "alpha" | "omega"
301 in let to_eol_re = /quorum_(up|down)/
302 in let ip_port_re = "sorry_server"
303 in field num_re sto_num
304 | field word_re sto_word
306 | field to_eol_re sto_to_eol
307 | field ip_port_re ip_port
308 | named_block_arg "real_server" "ip" "port" real_server_field
310 (* View: virtual_server *)
311 let virtual_server = named_block_arg "virtual_server" "ip" "port" virtual_server_field
313 (* View: virtual_server_group_field *)
314 let virtual_server_group_field = [ indent . label "vip"
317 . [ label "port" . sto_num ]
320 (* View: virtual_server_group *)
321 let virtual_server_group = named_block "virtual_server_group" virtual_server_group_field
324 contains subblocks of Virtual server group(s) and Virtual server(s) *)
325 let lvs_conf = virtual_server | virtual_server_group
331 let lns = ( empty | comment | global_conf | vrrpd_conf | lvs_conf )*
333 (* Variable: filter *)
334 let filter = incl "/etc/keepalived/keepalived.conf"
336 let xfm = transform lns filter