#!/usr/bin/perl # # Module: vyatta-keepalived.pl # # **** License **** # Version: VPL 1.0 # # The contents of this file are subject to the Vyatta Public License # Version 1.0 ("License"); you may not use this file except in # compliance with the License. You may obtain a copy of the License at # http://www.vyatta.com/vpl # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. # All Rights Reserved. # # Author: Stig Thormodsrud # Date: October 2007 # Description: Script to glue vyatta cli to keepalived daemon # # **** End License **** # use lib "/opt/vyatta/share/perl5/"; use VyattaConfig; use VyattaKeepalived; use Getopt::Long; use strict; use warnings; sub keepalived_get_values { my ($intf) = @_; my $output; my $config = new VyattaConfig; $config->setLevel("interfaces ethernet $intf vrrp"); my $group = $config->returnValue("vrrp-group"); if (!defined $group) { $group = 1; } my $vip = $config->returnValue("virtual-address"); if (!defined $vip) { print "must define a virtual-address for vrrp-group $group\n"; exit 1; } my $priority = $config->returnValue("priority"); if (!defined $priority) { $priority = 1; } my $preempt = $config->returnValue("preempt"); if (!defined $preempt) { $preempt = "true"; } my $advert_int = $config->returnValue("advertise-interval"); if (!defined $advert_int) { $advert_int = 1; } $config->setLevel("interfaces ethernet $intf vrrp authentication"); my $auth_type = $config->returnValue("type"); my $auth_pass; if (defined $auth_type) { $auth_type = uc($auth_type); $auth_pass = $config->returnValue("password"); if (! defined $auth_pass) { print "vrrp authentication password not set"; exit 1; } } my $state_transition_script = VyattaKeepalived::get_state_script(); $output = "vrrp_instance vyatta-$intf-$group \{\n"; if ($preempt eq "false") { $output .= "\tstate BACKUP\n"; } else { $output .= "\tstate MASTER\n"; } $output .= "\tinterface $intf\n"; $output .= "\tvirtual_router_id $group\n"; $output .= "\tpriority $priority\n"; if ($preempt eq "false") { $output .= "\tnopreempt\n"; } $output .= "\tadvert_int $advert_int\n"; if (defined $auth_type) { $output .= "\tauthentication {\n"; $output .= "\t\tauth_type $auth_type\n"; $output .= "\t\tauth_pass $auth_pass\n\t}\n"; } $output .= "\tvirtual_ipaddress \{\n"; $output .= "\t\t$vip\n"; $output .= "\t\}\n"; $output .= "\tnotify_master "; $output .= "\"$state_transition_script master $intf $group $vip\" \n"; $output .= "\tnotify_backup "; $output .= "\"$state_transition_script backup $intf $group $vip\" \n"; $output .= "\t notify_fault "; $output .= "\"$state_transition_script fault $intf $group $vip\" \n"; $output .= "\}\n"; return $output; } sub vrrp_update_config { my $output; my $config = new VyattaConfig; # todo: support vifs $config->setLevel("interfaces ethernet"); my @eths = $config->listNodes(); my $vrrp_instances = 0; foreach my $eth (@eths) { $config->setLevel("interfaces ethernet $eth"); if ($config->exists("vrrp")) { $output .= keepalived_get_values($eth); $vrrp_instances++; } } if ($vrrp_instances > 0) { my $conf_file = VyattaKeepalived::get_conf_file(); keepalived_write_file($conf_file, $output); VyattaKeepalived::restart_daemon($conf_file); } return $vrrp_instances; } sub keepalived_write_file { my ($file, $data) = @_; open(my $fh, '>', $file) || die "Couldn't open $file - $!"; print $fh $data; close $fh; } # # main # my ($action, $vrrp_intf, $vrrp_group); GetOptions("vrrp-action=s" => \$action, "intf=s" => \$vrrp_intf, "group=s" => \$vrrp_group); if (! defined $action) { print "no action\n"; exit 1; } if ($action eq "update") { my $vrrp_instances = vrrp_update_config(); VyattaKeepalived::vrrp_log("vrrp update $vrrp_intf $vrrp_instances"); if ($vrrp_instances == 0) { VyattaKeepalived::stop_daemon(); } } if ($action eq "delete") { if (! defined $vrrp_intf || ! defined $vrrp_group) { print "must include interface & group"; exit 1; } my $state_file = VyattaKeepalived::get_state_file($vrrp_intf, $vrrp_group); system("rm $state_file"); VyattaKeepalived::vrrp_log("vrrp delete $vrrp_intf $vrrp_group"); exit 0; } exit 0; # end of file