Difference between revisions of "PluginsDummyCode"
(Created page with "# dhcp.pm # # The dhcp plugin package dhcp; @ISA = qw(Exporter); @EXPORT = qw(createPlugin bootingCreateFiles bootingCommands execCreateF...") |
|||
Line 1: | Line 1: | ||
+ | <pre> | ||
# dhcp.pm | # dhcp.pm | ||
# | # | ||
Line 806: | Line 807: | ||
1 | 1 | ||
+ | </pre> |
Revision as of 09:48, 21 July 2011
# dhcp.pm # # The dhcp plugin package dhcp; @ISA = qw(Exporter); @EXPORT = qw(createPlugin bootingCreateFiles bootingCommands execCreateFiles execCommands shutdownCommand finalizePlugin); ########################################################### # Modules no import ########################################################### use strict; use Net::Netmask; 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 ########################################################### # Global variables ########################################################### my $globalNode; my $valid_fail; ########################################################### # Subroutines ########################################################### ########################################################### # createPlugin # # 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; print "dhcp: $conf\n"; 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 $type; 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 ){ $type = $virtualm->getAttribute("type"); switch ($type) { case "dhcp3" { my $serverTagList = $virtualm->getElementsByTagName("server"); my $numservers = $serverTagList->getLength; if ( $numservers == 1 ) { # open filehandle to create /etc/dhcp3/dhcpd.conf file my $server_file = "/tmp/$vm" . "_server.conf"; chomp( my $date = `date` ); open( SERVER, ">$server_file" ) or $files{"ERROR"} = "Cannot open $server_file file"; # server.conf file defaults print SERVER "# server.conf file generated by dhcp.pm VNUML plugin at $date\n\n"; print SERVER "ddns-update-style none;\n"; print SERVER "default-lease-time 120;\n"; print SERVER "max-lease-time 120;\n"; #print SERVER "log-facility local7;\n\n"; # extract configuration from subnet blocks in dhcp_conf.xml my $server = $serverTagList->item(0); my $subnetTagList = $server->getElementsByTagName("subnet"); my $numsubnets = $subnetTagList->getLength; for ( my $ns=0; $ns < $numsubnets ; $ns++ ) { my $subnet = $subnetTagList->item($ns); my $ipTagList = $subnet->getElementsByTagName("ip"); my $numip = $ipTagList->getLength; # subnet declaration my $ipTag = $ipTagList->item($0); my $subnetmask = $ipTag->getAttribute("mask"); my $subnetbaseip = $ipTag->getFirstChild->getData; my $block = new Net::Netmask("$subnetbaseip"."/"."$subnetmask"); my $baseip = $block->base(); my $mask = $block->mask(); print SERVER "subnet $baseip netmask $mask {\n"; # extract ip ranges in subnet my $rangeTagList = $subnet->getElementsByTagName("range"); my $numranges = $rangeTagList->getLength; for ( my $nr = 0; $nr < $numranges ; $nr++ ) { my $rangeTag = $rangeTagList->item($nr); my $firstTagList = $rangeTag->getElementsByTagName("first"); my $firstTag = $firstTagList->item(0); my $firstip = $firstTag->getFirstChild->getData; my $lastTagList = $rangeTag->getElementsByTagName("last"); my $lastTag = $lastTagList->item(0); my $lastip = $lastTag->getFirstChild->getData; print SERVER " range $firstip $lastip;\n"; } # extract routers in subnet (if any) my $routerTagList = $subnet->getElementsByTagName("router"); my $numrouters = $routerTagList->getLength; if ( $numrouters > 0 ) { print SERVER " option routers"; for ( my $nr = 0; $nr < $numrouters ; $nr++ ) { if ( $nr > 0 ) { print SERVER ","; } my $routerTag = $routerTagList->item($nr); my $router = $routerTag->getFirstChild->getData; print SERVER " $router"; } print SERVER ";\n"; } # extract dns in subnet (if any) my $dnsTagList = $subnet->getElementsByTagName("dns"); my $numdns = $dnsTagList->getLength; if ( $numdns > 0 ) { print SERVER " option domain-name-servers"; for ( my $nd = 0; $nd < $numdns ; $nd++ ) { if ( $nd > 0 ) { print SERVER ","; } my $dnsTag = $dnsTagList->item($nd); my $dns = $dnsTag->getFirstChild->getData; print SERVER " $dns"; } print SERVER ";\n"; } # extract domain in subnet (if specified) my $domainTagList = $subnet->getElementsByTagName("domain"); my $numdomains = $domainTagList->getLength; if ( $numdomains == 1 ) { my $domainTag = $domainTagList->item(0); my $domain = $domainTag->getFirstChild->getData; print SERVER " option domain-name \"$domain\";\n"; } # end subnet declaration in configuration file print SERVER "}\n\n"; # extract hosts in subnet (if any) my $hostTagList = $subnet->getElementsByTagName("host"); my $numhosts = $hostTagList->getLength; for ( my $nh = 0; $nh < $numhosts ; $nh++ ) { my $hostTag = $hostTagList->item($nh); my $hostname = $hostTag->getAttribute("name"); my $hostmac = $hostTag->getAttribute("mac"); my $hostip = $hostTag->getAttribute("ip"); # ignore unmatching host declarations if ( $block->match($hostip) ) { print SERVER "host $hostname {\n hardware ethernet $hostmac;\n fixed-address $hostip;\n}\n\n"; } } } close(SERVER); $files{"/etc/dhcp3/dhcpd.conf"} = $server_file; } my $relayTagList = $virtualm->getElementsByTagName("relay"); my $numrelays = $relayTagList->getLength; if ( $numrelays == 1 ) { # Build file /etc/default/dhcp3-relay.conf my $relay_file = "/tmp/$vm" . "_relay.conf"; chomp( my $date = `date` ); open( RELAY, ">$relay_file" ) or $files{"ERROR"} = "Cannot open $relay_file file"; print RELAY "# relay.conf file generated by dhcp.pm VNUML plugin at $date\n"; print RELAY "SERVERS=\""; my $relay = $relayTagList->item(0); my $toserverTagList = $relay->getElementsByTagName("toserver"); my $numtoservers = $toserverTagList->getLength; for ( my $nt = 0; $nt < $numtoservers ; $nt++ ) { my $toserverTag = $toserverTagList->item($nt); my $toserverData = $toserverTag->getFirstChild->getData; print RELAY "$toserverData "; } print RELAY "\"\n"; close(RELAY); $files{"/etc/default/dhcp3-relay"} = $relay_file; } my $clientTagList = $virtualm->getElementsByTagName("client"); my $numclients = $clientTagList->getLength; if ( $numclients == 1 ) { # Build file /etc/dhcp3/dhclient.conf my $client_file = "/tmp/$vm" . "_client.conf"; chomp( my $date = `date` ); open( CLIENT, ">$client_file" ) or $files{"ERROR"} = "Cannot open $client_file file"; print CLIENT "# Configuration file for /sbin/dhclient, which is included in Debian's dhcp3-client package.\n"; print CLIENT "# client.conf file generated by dhcp.pm VNUML plugin at $date\n\n"; print CLIENT "send host-name \"<hostname>\";\n"; print CLIENT "request subnet-mask, broadcast-address, time-offset, routers, domain-name, domain-name-servers, domain-search, host-name, netbios-name-servers, netbios-scope, interface-mtu;\n"; print CLIENT "retry 10;\n"; close(CLIENT); $files{"/etc/dhcp3/dhclient.conf"} = $client_file; } }else{ $files{"ERROR"} = "Your choice $type for $vm is not a recognized type (yet)\n"; } } } } return %files; } ########################################################### # bootingCommands # # To be called during "t" mode, for each vm in the scenario # # Arguments: # - vm name # # Returns: # - list of commands to execute in the virtual machine at booting time # ########################################################### sub bootingCommands { } ########################################################### # execVmsToUse # # To be called once during "x" mode # # Arguments: # - seq command sequence # # Returns: # - list of virtual machines where the command has effect # ########################################################### sub execVmsToUse { my $self = shift; my $seq = shift; # Four lists are built, one is returned depending on the executed command my @vm_list = (); my @server_vm_list = (); my @relay_vm_list = (); my @client_vm_list = (); 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"); push (@vm_list,$virtualm_name); my $serverTagList = $virtualm->getElementsByTagName("server"); my $numservers = $serverTagList->getLength; my $relayTagList = $virtualm->getElementsByTagName("relay"); my $numrelays = $relayTagList->getLength; my $clientTagList = $virtualm->getElementsByTagName("client"); my $numclients = $clientTagList->getLength; if ( $numservers == 1 ) { push (@server_vm_list,$virtualm_name); } if ( $numrelays == 1 ) { push (@relay_vm_list,$virtualm_name); } if (!($numclients == 0)) { push (@client_vm_list,$virtualm_name); } } if ($seq eq "start" || $seq eq "restart" || $seq eq "stop" || $seq eq "dhcp-start" || $seq eq "dhcp-restart" || $seq eq "dhcp-stop") { return @vm_list; }elsif ($seq eq "dhcp-server-start"|| $seq eq "dhcp-server-stop" || $seq eq "dhcp-server-restart" || $seq eq "dhcp-server-force-reload"){ return @server_vm_list; }elsif ( $seq eq "dhcp-relay-start"|| $seq eq "dhcp-relay-restart"|| $seq eq "dhcp-relay-stop"|| $seq eq "dhcp-relay-force-reload"){ return @relay_vm_list; }elsif ($seq eq "dhcp-client-start"||$seq eq "dhcp-client-restart"||$seq eq "dhcp-client-stop"){ return @client_vm_list; }else{ return (); } } ########################################################### # 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 { } ########################################################### # 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 <exec> processing ########################################################### sub execCommands { my $self = shift; my $vm = shift; my $seq = shift; my @commands; my $type; 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"); switch ($type) { case "dhcp3" { # recognized type } else { unshift( @commands, "Your choice $type for $vm is not a recognized type (yet)\n"); } } my $serverTagList = $virtualm->getElementsByTagName("server"); my $numservers = $serverTagList->getLength; my $relayTagList = $virtualm->getElementsByTagName("relay"); my $numrelays = $relayTagList->getLength; my $clientTagList = $virtualm->getElementsByTagName("client"); my $numclients = $clientTagList->getLength; switch ($seq){ case ["start","dhcp-start"]{ # Start server, relay and clients in the virtual machine, if any unshift( @commands, "" ); if ( $numservers == 1 ) { push( @commands, "/etc/init.d/dhcp3-server start" ); } if ( $numrelays == 1 ) { push( @commands, "/etc/init.d/dhcp3-relay start" ); } if (!($numclients == 0)) { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient eth"."$ifData"); } } } } case ["restart","dhcp-restart"]{ # Restart server, relay and clients in the virtual machine, if any unshift( @commands, "" ); if ( $numservers == 1 ) { push( @commands, "/etc/init.d/dhcp3-server restart" ); } if ( $numrelays == 1 ) { push( @commands, "/etc/init.d/dhcp3-relay restart" ); } if (!($numclients == 0)) { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient -r"); push(@commands,"killall dhclient"); push(@commands,"dhclient eth"."$ifData"); } } } } case ["stop","dhcp-stop"]{ # Stop server and relay in the virtual machine, if any unshift( @commands, "" ); if ( $numservers == 1 ) { push( @commands, "/etc/init.d/dhcp3-server stop" ); } if ( $numrelays == 1 ) { push( @commands, "/etc/init.d/dhcp3-relay stop" ); } if (!($numclients == 0)) { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient -r"); push(@commands,"killall dhclient"); } } } } case ("dhcp-server-start"){ # Start the server in the virtual machine. Return error if there isn't any. if ( $numservers == 0 ) { unshift( @commands, "$vm is not configured as a dhcp server. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-server start" ); } } case ("dhcp-relay-start"){ # Start the relay in the virtual machine. Return error if there isn't any. if ( $numrelays == 0 ) { unshift( @commands, "$vm is not configured as a dhcp relay. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-relay start" ); } } case ("dhcp-client-start"){ # Start the clients in the virtual machine. Return error if there aren't any. if ( $numclients == 0 ) { unshift( @commands, "$vm is not configured as a dhcp client. Choose the appropriate virtual machine with flag -M name" ); } else { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient eth"."$ifData"); } } } } case ("dhcp-server-restart"){ # Restart the server in the virtual machine. Return error if there isn't any. if ( $numservers == 0 ) { unshift( @commands, "$vm is not configured as a dhcp server. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-server restart" ); } } case ("dhcp-relay-restart"){ # Restart the relay in the virtual machine. Return error if there isn't any. if ( $numrelays == 0 ) { unshift( @commands, "$vm is not configured as a dhcp relay. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-relay restart" ); } } case ("dhcp-client-restart"){ # Start the clients in the virtual machine. Return error if there aren't any. if ( $numclients == 0 ) { unshift( @commands, "$vm is not configured as a dhcp client. Choose the appropriate virtual machine with flag -M name" ); } else { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient -r"); push(@commands,"killall dhclient"); push(@commands,"dhclient eth"."$ifData"); } } } } case ("dhcp-server-stop"){ # Stop the server in the virtual machine. Return error if there isn't any. if ( $numservers == 0 ) { unshift( @commands, "$vm is not configured as a dhcp server. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-server stop" ); } } case ("dhcp-relay-stop"){ # Stop the relay in the virtual machine. Return error if there isn't any. if ( $numrelays == 0 ) { unshift( @commands, "$vm is not configured as a dhcp relay. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-relay stop" ); } } case ("dhcp-client-stop"){ # Start the clients in the virtual machine. Return error if there aren't any. if ( $numclients == 0 ) { unshift( @commands, "$vm is not configured as a dhcp client. Choose the appropriate virtual machine with flag -M name" ); } else { unshift(@commands, "" ); my $client = $clientTagList->item(0); my $ifTagList = $client->getElementsByTagName("if"); my $numif = $ifTagList->getLength; for (my $ni=0; $ni<$numif ; $ni++) { my $ifTag = $ifTagList->item($ni); my $ifData = $ifTag->getFirstChild->getData; if (!($ifData == 0)) { push(@commands,"dhclient -r"); push(@commands,"killall dhclient"); } } } } case ("dhcp-server-force-reload"){ # Force reload of the server in the virtual machine. Return error if there isn't any. if ( $numservers == 0 ) { unshift( @commands, "$vm is not configured as a dhcp server. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-server force-reload" ); } } case ("dhcp-relay-force-reload"){ # Force reload of the relay in the virtual machine. Return error if there isn't any. if ( $numservers == 0 ) { unshift( @commands, "$vm is not configured as a dhcp relay. Choose the appropriate virtual machine with flag -M name" ); } else { unshift( @commands, "" ); push( @commands, "/etc/init.d/dhcp3-relay force-reload" ); } }else{ unshift( @commands, "\nYour choice \"$seq\" is not a recognized command (yet).\nAvailable commands: start, stop, restart, dhcp-start, dhcp-stop, dhcp-restart, dhcp-server-start, dhcp-server-stop, dhcp-server-restart, dhcp-server-force-reload, dhcp-relay-start, dhcp-relay-stop, dhcp-relay-restart, dhcp-relay-force-reload, dhcp-client-start.\n" ); } } return @commands; } } } ########################################################### # shutdownCommands # # To be called during "d" mode, for each vm in the scenario # # Arguments: # - vm name # # Returns: # - list of commands to execute in the virtual machine at shutdown time # ########################################################### sub shutdownCommands { my $self = shift; my $vm = shift; my @commands; my $type; 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"); switch ($type) { case "dhcp3" { unshift( @commands, "" ); my $serverTagList = $virtualm->getElementsByTagName("server"); my $numservers = $serverTagList->getLength; if ( $numservers == 1 ) { push( @commands, "/etc/init.d/dhcp3-server stop" ); } my $relayTagList = $virtualm->getElementsByTagName("relay"); my $numrelays = $relayTagList->getLength; if ( $numrelays == 1 ) { push( @commands, "/etc/init.d/dhcp3-relay stop" ); } } else { unshift( @commands,"Your choice $type for $vm is not a recognized type (yet)\n"); } } } return @commands; } } ############################################################# # finalizePlugin # # To be called always, just before ending the procesing the scenario specification # # Arguments: # - none # # Returns: # - none # ############################################################# sub finalizePlugin { } ############################################################# # # Checks existence and semantics in ospf conf file. # Currently this check consist in: # # 1. Configuration file exists. # 2. Check DTD. # 3. IP tag contains mask attribute and data. # 4. Area tag is unique and contains data. # ############################################################# 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 DHCP plugin file\n"); } $globalNode = $dom_tree->getElementsByTagName("dhcp_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