1(* 2Module: Keepalived 3 Parses /etc/keepalived/keepalived.conf 4 5Author: Raphael Pinson <raphink@gmail.com> 6 7About: Reference 8 This lens tries to keep as close as possible to `man 5 keepalived.conf` where possible. 9 10About: License 11 This file is licenced under the LGPL v2+, like the rest of Augeas. 12 13About: Lens Usage 14 To be documented 15 16About: Configuration files 17 This lens applies to /etc/keepalived/keepalived.conf. See <filter>. 18 19About: Examples 20 The <Test_Keepalived> file contains various examples and tests. 21*) 22 23 24module Keepalived = 25 autoload xfm 26 27(************************************************************************ 28 * Group: USEFUL PRIMITIVES 29 *************************************************************************) 30 31(* Group: Comments and empty lines *) 32 33(* View: indent *) 34let indent = Util.indent 35 36(* View: eol *) 37let eol = Util.eol 38 39(* View: opt_eol *) 40let opt_eol = del /[ \t]*\n?/ " " 41 42(* View: sep_spc *) 43let sep_spc = Sep.space 44 45(* View: comment 46Map comments in "#comment" nodes *) 47let comment = Util.comment_generic /[ \t]*[#!][ \t]*/ "# " 48 49(* View: comment_eol 50Map comments at eol *) 51let comment_eol = Util.comment_generic /[ \t]*[#!][ \t]*/ " # " 52 53(* View: comment_or_eol 54A <comment_eol> or <eol> *) 55let comment_or_eol = comment_eol | (del /[ \t]*[#!]?\n/ "\n") 56 57(* View: empty 58Map empty lines *) 59let empty = Util.empty 60 61(* View: sto_email_addr *) 62let sto_email_addr = store Rx.email_addr 63 64(* Variable: word *) 65let word = Rx.word 66 67(* Variable: word_slash *) 68let word_slash = word | "/" 69 70(* View: sto_word *) 71let sto_word = store word 72 73(* View: sto_num *) 74let sto_num = store Rx.relinteger 75 76(* View: sto_ipv6 *) 77let sto_ipv6 = store Rx.ipv6 78 79(* View: sto_to_eol *) 80let sto_to_eol = store /[^#! \t\n][^#!\n]*[^#! \t\n]|[^#! \t\n]/ 81 82(* View: field *) 83let field (kw:regexp) (sto:lens) = indent . Build.key_value_line_comment kw sep_spc sto comment_eol 84 85(* View: flag 86A single word *) 87let flag (kw:regexp) = [ indent . key kw . comment_or_eol ] 88 89(* View: ip_port 90 An IP <space> port pair *) 91let ip_port = [ label "ip" . sto_word ] . sep_spc . [ label "port" . sto_num ] 92 93(* View: lens_block 94A generic block with a title lens. 95The definition is very similar to Build.block_newlines 96but uses a different type of <comment>. *) 97let lens_block (title:lens) (sto:lens) = 98 [ indent . title 99 . Build.block_newlines sto comment . eol ] 100 101(* View: block 102A simple block with just a block title *) 103let block (kw:regexp) (sto:lens) = lens_block (key kw) sto 104 105(* View: named_block 106A block with a block title and name *) 107let named_block (kw:string) (sto:lens) = lens_block (key kw . sep_spc . sto_word) sto 108 109(* View: named_block_arg_title 110A title lens for named_block_arg *) 111let named_block_arg_title (kw:string) (name:string) (arg:string) = 112 key kw . sep_spc 113 . [ label name . sto_word ] 114 . sep_spc 115 . [ label arg . sto_word ] 116 117(* View: named_block_arg 118A block with a block title, a name and an argument *) 119let named_block_arg (kw:string) (name:string) (arg:string) (sto:lens) = 120 lens_block (named_block_arg_title kw name arg) sto 121 122 123(************************************************************************ 124 * Group: GLOBAL CONFIGURATION 125 *************************************************************************) 126 127(* View: email 128A simple email address entry *) 129let email = [ indent . label "email" . sto_email_addr . comment_or_eol ] 130 131(* View: global_defs_field 132Possible fields in the global_defs block *) 133let global_defs_field = 134 let word_re = "smtp_server"|"lvs_id"|"router_id"|"vrrp_mcast_group4" 135 in let ipv6_re = "vrrp_mcast_group6" 136 in let num_re = "smtp_connect_timeout" 137 in block "notification_email" email 138 | field "notification_email_from" sto_email_addr 139 | field word_re sto_word 140 | field num_re sto_num 141 | field ipv6_re sto_ipv6 142 143(* View: global_defs 144A global_defs block *) 145let global_defs = block "global_defs" global_defs_field 146 147(* View: prefixlen 148A prefix for IP addresses *) 149let prefixlen = [ label "prefixlen" . Util.del_str "/" . sto_num ] 150 151(* View: ipaddr 152An IP address or range with an optional mask *) 153let ipaddr = label "ipaddr" . store /[0-9.-]+/ . prefixlen? 154 155(* View: ipdev 156A device for IP addresses *) 157let ipdev = [ key "dev" . sep_spc . sto_word ] 158 159(* View: static_ipaddress_field 160The whole string is fed to ip addr add. 161You can truncate the string anywhere you like and let ip addr add use defaults for the rest of the string. 162To be refined with fields according to `ip addr help`. 163*) 164let static_ipaddress_field = [ indent . ipaddr 165 . (sep_spc . ipdev)? 166 . comment_or_eol ] 167 168(* View: static_routes_field 169src $SRC_IP to $DST_IP dev $SRC_DEVICE 170*) 171let static_routes_field = [ indent . label "route" 172 . [ key "src" . sto_word ] . sep_spc 173 . [ key "to" . sto_word ] . sep_spc 174 . [ key "dev" . sto_word ] . comment_or_eol ] 175 176(* View: static_routes *) 177let static_routes = block "static_ipaddress" static_ipaddress_field 178 | block "static_routes" static_routes_field 179 180 181(* View: global_conf 182A global configuration entry *) 183let global_conf = global_defs | static_routes 184 185 186(************************************************************************ 187 * Group: VRRP CONFIGURATION 188 *************************************************************************) 189 190(*View: vrrp_sync_group_field *) 191let vrrp_sync_group_field = 192 let to_eol_re = /notify(_master|_backup|_fault)?/ 193 in let flag_re = "smtp_alert" 194 in field to_eol_re sto_to_eol 195 | flag flag_re 196 | block "group" [ indent . key word . comment_or_eol ] 197 198(* View: vrrp_sync_group *) 199let vrrp_sync_group = named_block "vrrp_sync_group" vrrp_sync_group_field 200 201(* View: vrrp_instance_field *) 202let vrrp_instance_field = 203 let word_re = "state" | "interface" | "lvs_sync_daemon_interface" 204 in let num_re = "virtual_router_id" | "priority" | "advert_int" | /garp_master_(delay|repeat|refresh|refresh_repeat)/ 205 in let to_eol_re = /notify(_master|_backup|_fault)?/ | /(mcast|unicast)_src_ip/ 206 in let flag_re = "smtp_alert" | "nopreempt" | "ha_suspend" | "debug" | "use_vmac" | "vmac_xmit_base" | "native_ipv6" | "dont_track_primary" | "preempt_delay" 207 in field word_re sto_word 208 | field num_re sto_num 209 | field to_eol_re sto_to_eol 210 | flag flag_re 211 | block "authentication" ( 212 field /auth_(type|pass)/ sto_word 213 ) 214 | block "virtual_ipaddress" static_ipaddress_field 215 | block /track_(interface|script)/ ( flag word ) 216 | block "unicast_peer" static_ipaddress_field 217 218(* View: vrrp_instance *) 219let vrrp_instance = named_block "vrrp_instance" vrrp_instance_field 220 221(* View: vrrp_script_field *) 222let vrrp_script_field = 223 let num_re = "interval" | "weight" | "fall" | "raise" 224 in let to_eol_re = "script" 225 in field to_eol_re sto_to_eol 226 | field num_re sto_num 227 228(* View: vrrp_script *) 229let vrrp_script = named_block "vrrp_script" vrrp_script_field 230 231 232(* View: vrrpd_conf 233contains subblocks of VRRP synchronization group(s) and VRRP instance(s) *) 234let vrrpd_conf = vrrp_sync_group | vrrp_instance | vrrp_script 235 236 237(************************************************************************ 238 * Group: REAL SERVER CHECKS CONFIGURATION 239 *************************************************************************) 240 241(* View: tcp_check_field *) 242let tcp_check_field = 243 let word_re = "bindto" 244 in let num_re = /connect_(timeout|port)/ 245 in field word_re sto_word 246 | field num_re sto_num 247 248(* View: misc_check_field *) 249let misc_check_field = 250 let flag_re = "misc_dynamic" 251 in let num_re = "misc_timeout" 252 in let to_eol_re = "misc_path" 253 in field num_re sto_num 254 | flag flag_re 255 | field to_eol_re sto_to_eol 256 257(* View: smtp_host_check_field *) 258let smtp_host_check_field = 259 let word_re = "connect_ip" | "bindto" 260 in let num_re = "connect_port" 261 in field word_re sto_word 262 | field num_re sto_num 263 264(* View: smtp_check_field *) 265let smtp_check_field = 266 let word_re = "connect_ip" | "bindto" 267 in let num_re = "connect_timeout" | "retry" | "delay_before_retry" 268 in let to_eol_re = "helo_name" 269 in field word_re sto_word 270 | field num_re sto_num 271 | field to_eol_re sto_to_eol 272 | block "host" smtp_host_check_field 273 274(* View: http_url_check_field *) 275let http_url_check_field = 276 let word_re = "digest" 277 in let num_re = "status_code" 278 in let to_eol_re = "path" 279 in field word_re sto_word 280 | field num_re sto_num 281 | field to_eol_re sto_to_eol 282 283(* View: http_check_field *) 284let http_check_field = 285 let num_re = /connect_(timeout|port)/ | "nb_get_retry" | "delay_before_retry" 286 in field num_re sto_num 287 | block "url" http_url_check_field 288 289(* View: real_server_field *) 290let real_server_field = 291 let num_re = "weight" 292 in let flag_re = "inhibit_on_failure" 293 in let to_eol_re = /notify_(up|down)/ 294 in field num_re sto_num 295 | flag flag_re 296 | field to_eol_re sto_to_eol 297 | block "TCP_CHECK" tcp_check_field 298 | block "MISC_CHECK" misc_check_field 299 | block "SMTP_CHECK" smtp_check_field 300 | block /(HTTP|SSL)_GET/ http_check_field 301 302(************************************************************************ 303 * Group: LVS CONFIGURATION 304 *************************************************************************) 305 306(* View: virtual_server_field *) 307let virtual_server_field = 308 let num_re = "delay_loop" | "persistence_timeout" | "quorum" | "hysteresis" 309 in let word_re = /lb_(algo|kind)/ | "nat_mask" | "protocol" | "persistence_granularity" 310 | "virtualhost" 311 in let flag_re = "ops" | "ha_suspend" | "alpha" | "omega" 312 in let to_eol_re = /quorum_(up|down)/ 313 in let ip_port_re = "sorry_server" 314 in field num_re sto_num 315 | field word_re sto_word 316 | flag flag_re 317 | field to_eol_re sto_to_eol 318 | field ip_port_re ip_port 319 | named_block_arg "real_server" "ip" "port" real_server_field 320 321(* View: virtual_server *) 322let virtual_server = named_block_arg "virtual_server" "ip" "port" virtual_server_field 323 324(* View: virtual_server_group_field *) 325let virtual_server_group_field = [ indent . label "vip" 326 . [ ipaddr ] 327 . sep_spc 328 . [ label "port" . sto_num ] 329 . comment_or_eol ] 330 331(* View: virtual_server_group *) 332let virtual_server_group = named_block "virtual_server_group" virtual_server_group_field 333 334(* View: lvs_conf 335contains subblocks of Virtual server group(s) and Virtual server(s) *) 336let lvs_conf = virtual_server | virtual_server_group 337 338 339(* View: lns 340 The keepalived lens 341*) 342let lns = ( empty | comment | global_conf | vrrpd_conf | lvs_conf )* 343 344(* Variable: filter *) 345let filter = incl "/etc/keepalived/keepalived.conf" 346 347let xfm = transform lns filter 348 349