PluginsOspfCode


 * 1) Ospfd.pm
 * 2) The ospfd plugin
 * 1) The ospfd plugin

package ospfd;

@ISA = qw(Exporter); @EXPORT = qw(createPlugin            bootingCreateFiles             bootingCommands             execCreateFiles             execCommands             shutdownCommand             finalizePlugin);


 * 1) Modules import
 * 1) Modules import

use strict; use XML::DOM;         					# XML management library use File::Basename;   					# File management library

use Switch;

use Socket;								# To resolve hostnames to IPs

use XML::DOM::ValParser;				# To check DTD


 * 1) Global variables
 * 1) Global variables

my $globalNode; my $valid_fail;


 * 1) Subroutines
 * 1) Subroutines

###########################################################	# Create plugin #	# To be called always, just before starting procesing the scenario specification #	# Arguments: # - the operation mode ("t","x","d" or "P") # - the plugin configuration file #	# Returns: # - an error message or 0 if all is ok	# #	###########################################################

sub createPlugin{ my $self = shift; my $mode = shift; my $conf = shift; my $error; eval{ $error = &checkConfigFile($conf); };	if ($@){ $error = $@; }	return $error; }

###########################################################	# bootingCreateFiles #	# To be called during "t" mode, for each vm in the scenario #	# Arguments: # - vm name #	# Returns: # - a hashname which keys are absolute pathnames of files in vm filesystem and #  values the the pathname of the file in the host filesystem. The file in the #  host filesytesm is removed after VNUML processed it, so temporal files in 	#   /tmp are preferable)	###########################################################

sub bootingCreateFiles{ my $self = shift; my $vm = shift; my %files; my $virtualmList=$globalNode->getElementsByTagName("vm"); my $longitud = $virtualmList->getLength; for (my $m=0; $m<$longitud; $m++){ my $virtualm = $virtualmList->item($m); my $virtualm_name = $virtualm->getAttribute("name"); if ($virtualm_name eq $vm){ my $zebra_file = "/tmp/$vm"."_zebra.conf"; my $ospfd_file = "/tmp/$vm"."_ospfd.conf"; my $zebraTagList = $virtualm->getElementsByTagName("zebra"); my $zebraTag = $zebraTagList->item($0); my $zebra_hostname = $zebraTag->getAttribute("hostname"); my $zebra_password = $zebraTag->getAttribute("password"); chomp(my $date = `date`); open(ZEBRA, ">$zebra_file") or $files{"ERROR"} = "Cannot open $zebra_file file"; print ZEBRA "! zebra.conf file generated by ospfd.pm VNUML plugin at $date\n"; print ZEBRA	"hostname $zebra_hostname\n"; print ZEBRA "password $zebra_password\n"; print ZEBRA "log file /var/log/zebra/zebra.log\n"; close (ZEBRA); open(OSPFD, ">$ospfd_file") or $files{"ERROR"} = "Cannot open $ospfd_file file"; print OSPFD "! ospfd.conf file generated by ospfd.pm VNUML plugin at $date\n"; print OSPFD "hostname $zebra_hostname\n"; print OSPFD "password $zebra_password\n"; print OSPFD "log file /var/log/zebra/ospfd.log\n!\n"; print OSPFD "router ospf\n"; my $networkTagList = $virtualm->getElementsByTagName("network"); my $longitudNetwork = $networkTagList->getLength; for (my $n=0; $n<$longitudNetwork; $n++){ my $networkTag = $networkTagList->item($n); my $ipTagList = $networkTag->getElementsByTagName("ip"); my $ipTag = $ipTagList->item($0); my $ipMask = $ipTag->getAttribute("mask"); my $ipData = $ipTag->getFirstChild->getData; my $areaTagList = $networkTag->getElementsByTagName("area"); my $areaTag = $areaTagList->item($0); my $areaData = $areaTag->getFirstChild->getData; print OSPFD " network $ipData/$ipMask area $areaData\n"; }			print OSPFD "!\n"; close (OSPFD); $files{"/etc/quagga/zebra.conf"} = $zebra_file; $files{"/etc/quagga/ospfd.conf"} = $ospfd_file; }	}	return %files; }

sub bootingCommands{ }

sub execVmsToUse {

my $self = shift; my $seq = shift; # The plugin has nothing to do for VMs with sequences other than # start, restart or stop, so in that case it returns an empty list unless ($seq eq "start" || $seq eq "ospf-start" || $seq eq "restart" || $seq eq "ospf-restart" || $seq eq "stop" || $seq eq "ospf-stop" || $seq eq "redoconf" || $seq eq "ospf-redoconf") { return ; }	my @vm_list = ;

my $virtualmList=$globalNode->getElementsByTagName("vm"); my $longitud = $virtualmList->getLength; for (my $m=0; $m<$longitud; $m++){ my $virtualm = $virtualmList->item($m); push (@vm_list,$virtualm->getAttribute("name")); }	return @vm_list; }	###########################################################	# execCreateFiles #	# To be called during "x" mode, for each vm in the scenario #	# Arguments: # - vm name # - seq command sequence #	# Returns: # - a hashname which kyes are absolute pathnames of files in vm filesystem and #  values the the pathname of the file in the host filesystem. The file in the #  host filesytesm is removed after VNUML processed it, so temporal files in 	#   /tmp are preferable)	#	########################################################### sub execCreateFiles{	my $self = shift;	my $vm = shift;	my $seq = shift;	my %files;	if (($seq eq "redoconf") || ($seq eq "ospf-redoconf")){

my $virtualmList=$globalNode->getElementsByTagName("vm"); my $longitud = $virtualmList->getLength; for (my $m=0; $m<$longitud; $m++){ my $virtualm = $virtualmList->item($m); my $virtualm_name = $virtualm->getAttribute("name"); if ($virtualm_name eq $vm){ my $zebra_file = "/tmp/$vm"."_zebra.conf"; my $ospfd_file = "/tmp/$vm"."_ospfd.conf"; my $zebraTagList = $virtualm->getElementsByTagName("zebra"); my $zebraTag = $zebraTagList->item($0); my $zebra_hostname = $zebraTag->getAttribute("hostname"); my $zebra_password = $zebraTag->getAttribute("password"); chomp(my $date = `date`); open(ZEBRA, ">$zebra_file") or $files{"ERROR"} = "Cannot open $zebra_file file"; print ZEBRA "! zebra.conf file generated by ospfd.pm VNUML plugin at $date\n"; print ZEBRA	"hostname $zebra_hostname\n"; print ZEBRA "password $zebra_password\n"; print ZEBRA "log file /var/log/zebra/zebra.log\n"; close (ZEBRA); open(OSPFD, ">$ospfd_file") or $files{"ERROR"} = "Cannot open $ospfd_file file"; print OSPFD "! ospfd.conf file generated by ospfd.pm VNUML plugin at $date\n"; print OSPFD "hostname $zebra_hostname\n"; print OSPFD "password $zebra_password\n"; print OSPFD "log file /var/log/zebra/ospfd.log\n!\n"; print OSPFD "router ospf\n"; my $networkTagList = $virtualm->getElementsByTagName("network"); my $longitudNetwork = $networkTagList->getLength; for (my $n=0; $n<$longitudNetwork; $n++){ my $networkTag = $networkTagList->item($n); my $ipTagList = $networkTag->getElementsByTagName("ip"); my $ipTag = $ipTagList->item($0); my $ipMask = $ipTag->getAttribute("mask"); my $ipData = $ipTag->getFirstChild->getData; my $areaTagList = $networkTag->getElementsByTagName("area"); my $areaTag = $areaTagList->item($0); my $areaData = $areaTag->getFirstChild->getData; print OSPFD " network $ipData/$ipMask area $areaData\n"; }				print OSPFD "!\n"; close (OSPFD); $files{"/etc/quagga/zebra.conf"} = $zebra_file; $files{"/etc/quagga/ospfd.conf"} = $ospfd_file; }		}	}	return %files; }

###########################################################	# execCommands #	# To be called during "x" mode, for each vm in the scenario #	# Arguments: # - vm name # - seq command sequence # 	# Returns: # - list of commands to execute in the virtual machine after processing ########################################################### sub execCommands{ my $self = shift; my $vm = shift; my $seq = shift; my @commands; my $type; my $subtype; my $zebra_bin = ""; my $ospfd_bin = ""; my $virtualmList=$globalNode->getElementsByTagName("vm"); my $longitud = $virtualmList->getLength; for (my $m=0; $m<$longitud; $m++){ my $virtualm = $virtualmList->item($m); my $virtualm_name = $virtualm->getAttribute("name"); if ( $vm eq $virtualm_name){ $type = $virtualm->getAttribute("type"); $subtype = $virtualm->getAttribute("subtype"); my $zebraBinTagList = $virtualm->getElementsByTagName("zebra_bin"); my $longitudZebra = $zebraBinTagList->getLength; if ($longitudZebra == 1){ $zebra_bin = $zebraBinTagList->item($0)->getFirstChild->getData; }			my $ospfdBinTagList = $virtualm->getElementsByTagName("ospfd_bin"); my $longitudOspfd = $ospfdBinTagList->getLength; if ($longitudOspfd == 1){ $ospfd_bin = $ospfdBinTagList->item($0)->getFirstChild->getData; }			switch ($type) { case "quagga"{ switch ($subtype){ case "lib-install"{ if ($zebra_bin eq ""){ $zebra_bin = "/usr/lib/quagga/zebra"; }							if ($ospfd_bin eq ""){ $ospfd_bin = "/usr/lib/quagga/ospfd"; }							unshift (@commands, ""); }						case "sbin-install"{ if ($zebra_bin eq ""){ $zebra_bin = "/usr/sbin/zebra"; }							if ($ospfd_bin eq ""){ $ospfd_bin = "/usr/sbin/ospfd"; }							unshift (@commands, ""); } else { unshift (@commands, "Your choice $subtype is not a recognized subtype (yet)\n"); }					}				} else { unshift (@commands, "Your choice $type is not a recognized type (yet)\n"); }			}			if (($seq eq "start") || ($seq eq "ospf-start")){ push (@commands, "$zebra_bin -d"); push (@commands, "$ospfd_bin -d"); }elsif(($seq eq "restart") || ($seq eq "ospf-restart")){ push (@commands, "killall zebra"); push (@commands, "killall ospfd"); push (@commands, "$zebra_bin -d"); push (@commands, "$ospfd_bin -d"); }elsif(($seq eq "stop") || ($seq eq "ospf-stop")){ push (@commands, "killall zebra"); push (@commands, "killall ospfd"); }		}	}	return @commands; }

sub finalizePlugin{ }

sub shutdownCommands{ }

#############################################################	#	# Checks existence and semantics in ospf conf file. # Currently this check consist in: #	#	1. Configuration file exists. #	2. Check DTD. #	#############################################################

sub checkConfigFile{ # 1. Configuration file exists. my $config_file = shift; open(FILEHANDLE, $config_file) or { return "cannot open config file $config_file\n", };	close (FILEHANDLE); # 2. Check DTD my $parser = new XML::DOM::ValParser; my $dom_tree; $valid_fail = 0; eval { local $XML::Checker::FAIL = \&validation_fail; $dom_tree = $parser->parsefile($config_file); };

if ($valid_fail) { return ("$config_file is not a well-formed OSPF plugin file\n"); }

$globalNode = $dom_tree->getElementsByTagName("ospf_conf")->item(0); return 0; }

sub validation_fail { my $code = shift; # To set flag $valid_fail = 1; # To print error message XML::Checker::print_error ($code, @_); }

1