Forum: Cfengine Help
Subject: Re: is it possible to combine arrays and lists?
Author: Seva Gluschenko
Link to topic: https://cfengine.com/forum/read.php?3,16807,16815#msg-16815
Neil, here is the almost real keepalived.conf (just IPs, names, and passwords
were changed):
! Configuration File for keepalived
global_defs {
router_id ID1
}
vrrp_instance ID1 {
state MASTER
interface eth1
virtual_router_id 111
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass some_pass
}
virtual_ipaddress {
172.16.0.11 label eth1:11
172.16.0.111 label eth1:111
}
notify_backup "/usr/local/bin/vrrp.sh BACKUP ID1"
notify_master "/usr/local/bin/vrrp.sh MASTER ID1"
notify_fault "/usr/local/bin/vrrp.sh FAULT ID1"
}
vrrp_instance ID2 {
state BACKUP
interface eth1
virtual_router_id 112
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass some_pass
}
virtual_ipaddress {
172.16.0.12 label eth1:12
172.16.0.112 label eth1:112
}
notify_backup "/usr/local/bin/vrrp.sh BACKUP ID2"
notify_master "/usr/local/bin/vrrp.sh MASTER ID2"
notify_fault "/usr/local/bin/vrrp.sh FAULT ID2"
}
The relevant dummy interfaces are configured as follows:
# cat /etc/sysconfig/network-scripts/ifcfg-dummy0\:112
DEVICE=dummy0:112
BOOTPROTO=none
ONBOOT=yes
IPADDR=172.16.0.112
NETMASK=255.255.255.255
TYPE=Ethernet
The servers are working in pairs, so I have ID1 and ID2 pair with swapped
master and slave instances, ID3 and ID4 pair etc. Each pair has its set of IPs,
router ids and virtual router ids, all remaining pieces of the configuration
are identical, so I believe it would be correct to build the configuration from
templates.
Well, I'm really not just sitting here and whining for somebody's help. I'm
wasting the whole today trying to troubleshoot this situation, and sometimes it
seems like things are only getting worse. After careful research I've got the
following setup which allows me to maintain only one instance of variables
without redefining them:
bundle common c
{
vars:
"external_eth" string => "eth1";
}
bundle agent vrrp
{
vars:
"id" string => "keepalived";
"cfg" string => "/etc/keepalived.conf";
"src" string => "vrrp.sh";
"scrpt" string => "/usr/local/bin/$(src)";
"dummy_iface" string =>
"/etc/sysconfig/network-scripts/ifcfg-dummy0";
vr1|vr2::
"net" string => "172.16.0";
"ip1" int => "40";
"ip2" int => "41";
vr3|vr4::
"net" string => "172.16.90";
"ip1" int => { "38", "138", "178" };
"ip2" int => { "39", "139", "179" };
vr1|vr3::
"my" ilist => { @(ip1) };
"his" ilist => { @(ip2) };
vr2|vr4::
"my" ilist => { @(ip2) };
"his" ilist => { @(ip1) };
files:
"$(cfg)"
comment => "Set up $(id) configuration file",
edit_line => vrrp_cf("$(net)", "$(scrpt)"),
edit_defaults => reconstruct,
perms => mo("400", "root");
"$(dummy_iface):$(my)"
comment => "Set up dummy interfaces",
edit_line => dummy_list("$(my)", "$(net)"),
edit_defaults => reconstruct,
perms => mog("555", "root", "root");
}
########################################################
bundle edit_line vrrp_cf(net, scrpt)
{
vars:
"ip1" ilist => { @(do_vrrp.my) };
"ip2" ilist => { @(do_vrrp.his) };
"pass" string => "some_pass";
"id" int => "20";
"id" int => "21";
"id" int => "22";
"id" int => "20";
vr1::
"my" string => "ID1";
"his" string => "ID2";
vr2::
"my" string => "ID2";
"his" string => "ID1";
vr3::
"my" string => "ID3";
"his" string => "ID4";
vr4::
"my" string => "ID4";
"his" string => "ID3";
any::
"nfy" string => "BACKUP";
"nfy" string => "MASTER";
"nfy" string => "FAULT";
"nlist" slist => getindices("nfy");
insert_lines:
"! Configuration File for keepalived, generated by Cfengine
global_defs {
router_id $(my)
}
vrrp_instance $(my) {
state MASTER
interface $(c.external_eth)
virtual_router_id $(id[$(my)])
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass $(pass)
}
virtual_ipaddress {
$(net).$(ip1) label $(c.external_eth):$(ip1)
}
notify_$(nlist) \"$(scrpt) $(nfy[$(nlist)]) $(item)\""
}
vrrp_instance $(his) {
state BACKUP
interface $(c.external_eth)
virtual_router_id $(id[$(his)])
priority 97
advert_int 1
authentication {
auth_type PASS
auth_pass $(pass)
}
virtual_ipaddress {
$(net).$(ip2) label $(c.external_eth):$(ip2)
}
notify_$(nlist) \"$(scrpt) $(nfy[$(nlist)]) $(item)\""
}
"
comment => "VRRP configuration";
}
Note that I don't even try to virtualize vrrp instances, just because I know
that iteration depth isn't enough. Well, wanna see the result for cf-agent -D
vr3 -f ./test.cf? Here it is:
! Configuration File for keepalived, generated by Cfengine
global_defs {
router_id ID3
}
vrrp_instance ID3 {
state MASTER
interface eth1
virtual_router_id 22
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass some_pass
}
virtual_ipaddress {
172.16.90.38 label eth1:38
}
notify_fault "/usr/local/bin/vrrp.sh FAULT ID3"
}
vrrp_instance ID4 {
state BACKUP
interface eth1
virtual_router_id 20
priority 97
advert_int 1
authentication {
auth_type PASS
auth_pass some_pass
}
virtual_ipaddress {
172.16.90.39 label eth1:39
}
notify_fault "/usr/local/bin/vrrp.sh FAULT ID4"
}
172.16.90.138 label eth1:138
172.16.90.178 label eth1:178
notify_master "/usr/local/bin/vrrp.sh MASTER ID3"
notify_master "/usr/local/bin/vrrp.sh MASTER ID4"
notify_backup "/usr/local/bin/vrrp.sh BACKUP ID3"
notify_backup "/usr/local/bin/vrrp.sh BACKUP ID4"
172.16.90.139 label eth1:139
172.16.90.179 label eth1:179
Fantastic, eh?
That happens because of list iteration disorder which I've reported already to
the bug tracker, but for the moment nobody seems to be interested.
So I mark the places where to insert lines with comments:
virtual_ipaddress { ! backup interfaces
}
! backup notices
and then insert lines there with the separate promise like this:
" $(net).$(ip1) label $(c.external_eth):$(ip1)"
location => after(".*! master interfaces");
It produces a lot of warnings:
!! insert_lines promise uses the same select_line_matching anchor as another
promise. This will lead to non-convergent behaviour.
Promise (version not specified) belongs to bundle 'vrrp_cf' in file
'./vrrptest.cf' near line 252
But at least it works.
_______________________________________________
Help-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/help-cfengine