# $Id: //depot/prod/test/nacldev/lib/NACL/MTask/NetworkUtils.pm#9 $ # # Copyright (c) 2011-2012 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary utility library for Networking functionalities ## @author benjaram@netapp.com, dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::MTask::NetworkUtils =head1 DESCRIPTION C is a PERL library which provides different methods which can be used in various Tasks and Automation of Networking Functionalities. All the methods are exported to the users. =cut package NACL::MTask::NetworkUtils; use strict; use warnings; use vars qw (@ISA %EXPORT_TAGS @EXPORT_OK); use Tharn qw(host ); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use Net::IP qw(:PROC); use NACL::APISet; use Params::Validate qw(validate validate_with BOOLEAN SCALAR OBJECT ARRAYREF); use NACL::ComponentUtils qw( _hash_copy ); use NACL::C::Component; use NACL::STask::NetworkInterface; use NACL::C::NetworkInterfaceCdb; use NACL::C::Route; use NATE::Time qw(timeout2time); use NATE::Exceptions::Argument; use NACL::APISet::Exceptions::ResponseException qw(:try); use NACL::STask::NetworkRoute; use base qw/NACL::MTask::MTask/; use Net::IP qw(ip_is_ipv6); @ISA = qw(Exporter); @EXPORT_OK = qw( verify_ip network_configurations_check ping ); =head1 METHODS =head2 verify_ip verify_ip(ip => $ip_address, shell_type => $shell_type); This method checks whether the IP (C) passed exists are not. It checks in ngsh, sk and BSD shell based on the option shell_type which defaults to all. If the IP doesn't exists in any of the shells, this method will returns 0 and returns 1 if the IP exists. Uses a NACL::C::Ifconfig.pm for 7Mode and NACL::C::NetworkInterface.pm for CMode. =over =item Options =over =item C<< command_interface => $command_interface >> (Required) A component object that represents the host to which to send commands. See L. =item C<< ip => $ip_address >> (Required)Ip address to verify. =item C<< ip => $shell_type default - all >> (optional)Ip address to verify =back =back =cut sub verify_ip { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'ip' => { type => SCALAR }, 'shell_type' => { type => SCALAR, optional => 1 }, }, allow_extra => 1 # To allow the common options through ); my $command_interface = delete $opts{command_interface}; my $shell_type = delete $opts{shell_type} || 'all'; my $ip = delete $opts{ip}; my $verify = 0; my $address; my $reference; if ( $ip !~ /::/ ) { $address = 'ipv4'; } else { $address = 'ipv6'; } if ( $shell_type =~ /BSD/i || $shell_type =~ /all/i ) { my $apiset = $command_interface->apiset( category => 'Node', interface => 'CLI', set => 'Systemshell' ); $apiset->set_privilege( "privilege-level" => "root" ); my $response = $apiset->ifconfig( 'all' => 1 ); my $output = $response->get_parsed_output(); foreach my $inet (@$output) { last if ($verify); $reference = $inet->{$address}; my $add; foreach $add ( @{$reference} ) { if ( $add->{address} =~ /$ip/ ) { $verify++; last; } } } ## end foreach my $inet (@$output) } ## end if ($shell_type =~ /BSD/i... if ( $shell_type =~ /ngsh/i || $shell_type =~ /all/i ) { try { NACL::STask::NetworkInterface->find( command_interface => $command_interface, filter => { address => $ip }, ); $verify++; } catch NACL::APISet::Exceptions::ResponseException with { my $e = shift; if ( $e->text =~ /There are no entries matching your query/i ) { $Log->trace("The IP address not found in the ngsh shell"); } }; } ## end if ($shell_type =~ /ngsh/i... if ( $shell_type =~ /sk/i || $shell_type =~ /all/i ) { my $apiset_obj = $command_interface->get_7m_or_nodescope_apiset(); my $response_obj = $apiset_obj->ifconfig( 'all' => '1' ); my $output = $response_obj->get_parsed_output(); my $flag = 0; foreach my $inet (@$output) { last if ($flag); $reference = $inet->{$address}; foreach my $addr ( @{$reference} ) { if ( $addr eq $ip ) { $verify++; $flag = 1; last; } } } ## end foreach my $inet (@$output) } ## end if ($shell_type =~ /sk/i... if ( $shell_type =~ /all/i && $verify < 3 ) { return 0; } $Log->exit() if $may_exit; return $verify; } ## end sub verify_ip =head2 ping ping( command_interface => $Node, node => $Node->node(), destination => $destination, count => '3', nacltask_verify => $type, ); } The method verifies the ping in ngsh, BSD, nodescope, windows, linux & Solaris. It executes the ping command for five iterations along with the parameters passed. The task supports IPv6 also. It checks for the pass rate of minimum 80% by default or the pass rate can be got from the user , if it is executed in the systemshell or at any of the clients(linux & windows). For nodes & Solaris, it checks whether the node is alive or dead. For successful ping, the value returned is 1, on failure returns 0. This method should be able to ping from source_node to destination_node where the destination will be either host or node. =over =item Options =over =item C<< command_interface => $command_interface >> (Required) The command interface on which ping is executed. See NACL::C::Component::command_interface The task support all the parameter specified in Component. =item C<< nacltask_shell_type => $arrayref default - sk on 7mode|ngsh on cmode >> (optional Not Applicable for Linux, Solaris & Windows) Do the verifications on specific shell type. The type can be ngsh, sk and bsd. Example : nacltask_shell_type => [ qw (sk bsd) ] =item C<< nacltask_pass_rate => $passrate >> (optional) Default is 80% =item C<< nacltask_polling_interval => $interval >> (Optional) Check the ping is reachable for every five seconds Default is 5 seconds. =item C<< nacltask_timeout => $nacltask_timeout >> (optional) Controls how long the command will wait before completing. Default is 300. Uses a 7Mode CLI or CMode CLI or Zapi, Windows or Solaris or Linux CLI. =back =back =cut sub ping { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { command_interface => { isa => 'NACL::C::CommandInterface' }, nacltask_shell_type => { type => ARRAYREF, default => undef }, destination => { type => SCALAR }, nacltask_pass_rate => { type => SCALAR, default => "80%" }, nacltask_timeout => { type => SCALAR, default => 300 }, nacltask_polling_interval => { type => SCALAR, default => 5}, }, allow_extra => 1 ); my $pass_rate = delete $opts{nacltask_pass_rate}; my $command_interface = $opts{command_interface}; my ($verify, $verify_bsd, $verify_ngsh, $verify_sk, $total_types, $type ); my $timeout = delete $opts{nacltask_timeout}; my $polling_interval = delete $opts{nacltask_polling_interval}; if ( $command_interface->hostrec->hosttype() =~ /filer/ ) { if ( !defined $opts{nacltask_shell_type} ) { $opts{nacltask_shell_type} = [qw( ngsh )] if ( $command_interface->mode() eq "CMode" ); $opts{nacltask_shell_type} = [qw( sk )] if ( $command_interface->mode() eq "7Mode" ); } my $type_passed = delete $opts{nacltask_shell_type}; $total_types = @$type_passed; $type = join( ".", @$type_passed ); $type = "all" if ( $type =~ /all/ ); my $destination = $opts{destination}; $verify = $type if ( $type eq "all" ); $verify_bsd = $type if ( $type =~ /bsd/ ); $verify_ngsh = $type if ( $type =~ /ngsh/ ); $verify_sk = $type if ( $type =~ /sk/ ); } else { delete $opts{nacltask_shell_type}; } my $verify_count = 0; if ( ( !defined $opts{node} ) && ( !$command_interface->isa('NACL::C::Client') ) ) { $opts{node} = $command_interface; } if ( !defined $opts{count} ) { $opts{count} = 5; } my $node = delete $opts{node} ; my $check = 0; require NACL::Exceptions::HostUnreachable; try { if ( $command_interface->isa('NACL::C::Client') ) { my $end_time = timeout2time($timeout); while ( time() < $end_time ) { $check = _taskverify_ping_host( %opts, pass_rate => $pass_rate ); if($check) { $end_time = 0; } else { Tharn::snooze($polling_interval); } } } else { if ( ($verify) || ($verify_ngsh) ) { if ( $command_interface->mode() eq 'CMode' ) { my $end_time = timeout2time($timeout); my $catch; while ( time() < $end_time ) { try { require NACL::C::Network; if (Net::IP::ip_is_ipv6( $opts{destination})) { NACL::C::Network->ping6( %opts, 'node' => $node ); } else { NACL::C::Network->ping( %opts, 'node' => $node ); } $catch = 1; } catch NACL::Exceptions::HostUnreachable with { $catch = 0; }; if($catch) { $verify_count++; $check = 1; $Log->comment("Ping got passed in ngsh"); $end_time = 0; } else { Tharn::snooze($polling_interval); $Log->comment("Ping got failed in ngsh"); } } } else { $Log->comment( "Ping cannot be run for ngsh shell for 7Mode"); $verify_count++; } } ## end if (($verify) || ($verify_ngsh... if ( ($verify) || ($verify_bsd) ) { my $end_time = timeout2time($timeout); while ( time() < $end_time ) { $check = _taskverify_ping_systemshell( %opts, pass_rate => $pass_rate ); if ($check) { $verify_count++; $Log->comment("Ping got passed in systemshell"); $end_time = 0; } else { Tharn::snooze($polling_interval); $Log->comment("Ping got failed in systemshell"); } } } ## end if (($verify) || ($verify_bsd... if ( ($verify) || ($verify_sk) ) { my $end_time = timeout2time($timeout); while ( time() < $end_time ) { $check = _taskverify_ping_nodescope(%opts); if ($check) { $verify_count++; $Log->comment("Ping got passed in 7m_or_nodescope"); $end_time = 0; } else { Tharn::snooze($polling_interval); $Log->comment("Ping got failed in 7m_or_nodescope"); } } } $Log->exit() if $may_exit; if ( ( $verify_count == 3 ) && ( $type =~ /all/ ) ) { return 1; } elsif ( $verify_count == $total_types ) { return 1; } } ## end else [ if ($command_interface... } catch NACL::APISet::Exceptions::ResponseException with { my $e = shift; $Log->exit() if $may_exit; $e->throw(); }; $Log->exit() if $may_exit; return $check; } ## end sub ping sub _taskverify_ping_host { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'destination' => { type => SCALAR }, 'count' => { type => SCALAR, default => 5 }, }, allow_extra => 1 # To allow the common options through ); my $loss_rate; if ( $opts{pass_rate} =~ /(\S+?)%/ ) { $loss_rate = 100 - $1; } delete $opts{pass_rate}; require NACL::C::Client::Ping; my $command_interface = $opts{command_interface}; my $destination = $opts{destination}; my $type = $command_interface->hostrec->hosttype(); my $check = 0; try { my $state = NACL::C::Client::Ping->ping(%opts); if ( $type =~ /^unix-linux/ || $type =~ /^windows/ || $command_interface->hostrec->isa('Hostrec::LanForge::Fire') ) { if ( $state->loss_percent() =~ /(\S+?)%/ ) { my $loss = $1; $loss = int($loss); $check = 1 if ( $loss <= $loss_rate ); } } elsif ( $type =~ /^unix-solaris$/ ) { $check = 1 if ( $state->state() =~ /alive/ ); } else { require NATE::BaseException; NATE::BaseException->throw("unsupported host"); } } catch NACL::APISet::Exceptions::CommandFailedException with { my $e = shift; $check = 0 if ( $e->text() =~ /no answer|unknown host|No route to host|Network is unreachable/ ); } catch NACL::APISet::Exceptions::TimeoutException with { $check = 0; }; if ($check) { $Log->comment("Ping got passed in host $type to $destination"); } else { $Log->comment("Ping got failed in host $type to $destination"); } $Log->exit() if $may_exit; return $check; } ## end sub _taskverify_ping_host sub _taskverify_ping_systemshell { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'destination' => { type => SCALAR }, 'count' => { type => SCALAR, default => 5 }, }, allow_extra => 1 # To allow the common options through ); my $command_interface = delete $opts{command_interface}; my $destination = $opts{destination}; my $apiset = $command_interface->apiset( category => 'Node', interface => 'CLI', set => 'Systemshell' ); $apiset->set_privilege( "privilege-level" => "root" ); my $allowed_v4_options = [ qw( audible adaptive so-debug numeric quiet verbose count sweepmaxsize sweepminsize sweepincrsize interval preload time-to-live pattern source-address packet-size timeout waittime destination) ]; my $allowed_v6_options = [ qw(addrtype bufsiz count disable-v6 so-debug flood gateway reverse-lookup hoplimit interface wait preload minimum-mtu numeric probe-node exit pattern policy quiet audible-receive audible-transmit source-address packet-size timeout verbose hops host ) ]; my %args; my $allowed_options = $allowed_v4_options; my $cmd = 'ping'; if (Net::IP::ip_is_ipv6($destination) ) { $allowed_options = $allowed_v6_options; $cmd = 'ping6'; } NACL::C::Component->_hash_copy( source => \%opts, copy => $allowed_options, target => \%args, ); if (Net::IP::ip_is_ipv6($destination) ) { $args{host} = $destination; } my $loss_rate; if ( $opts{pass_rate} =~ /(\S+?)%/ ) { $loss_rate = 100 - $1; } delete $opts{pass_rate}; my $check = 0; try { my $response = $apiset->$cmd(%args); my $output = $response->get_parsed_output(); if ( $output->[0]->{loss} =~ /(\S+?)%/ ) { my $loss = $1; $loss = int($loss); if ( $loss <= $loss_rate ) { $check = 1; } } } catch NACL::APISet::Exceptions::CommandFailedException with { my $e = shift; $check = 0 if ( $e->text() =~ /no answer|unknown host|No route to host|Network is unreachable/ ); } catch NACL::APISet::Exceptions::TimeoutException with { $check = 0; }; $Log->exit() if $may_exit; return $check; } ## end sub _taskverify_ping_systemshell sub _taskverify_ping_nodescope { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'destination' => { type => SCALAR }, 'count' => { type => SCALAR, default => 5 }, }, allow_extra => 1 # To allow the common options through ); my $command_interface = $opts{command_interface}; my $destination = $opts{destination}; my $nodescope_apiset = $command_interface->get_7m_or_nodescope_apiset(); my ($method, $allowed_options); my %args; if ( Net::IP::ip_is_ipv6( $opts{destination} ) ) { $method = "ping6"; $allowed_options = [ qw(verbose bufsize count interface sourceaddr packetsize) ]; NACL::C::Component->_hash_copy( source => \%opts, copy => $allowed_options, target => \%args, map => { destination => 'host' }, ); } else { $method = "ping"; $allowed_options = [ qw( datagram-every-second record-route bypass-routing-tables verbose interface count destination packet-size) ]; NACL::C::Component->_hash_copy( source => \%opts, copy => $allowed_options, target => \%args, ); } my $check = 1; my $response; try { $nodescope_apiset->$method(%args); } catch NACL::APISet::Exceptions::CommandFailedException with { my $e = shift; if ( $e->text() =~ /no answer|unknown host|No route to host|Network is unreachable|ping/ ) { $check = 0; } } catch NACL::APISet::Exceptions::TimeoutException with { $check = 0; }; $Log->exit() if $may_exit; return $check; } ## end sub _taskverify_ping_nodescope =head2 network_configurations_check network_configurations_check( command_interface => $command_interface, lif => $lif, vserver => $vserver_name, 'routing-group' => $routing_group, destination => $destination, %other_options ); This method Verify the configurations of lifs & routes. Verify the operational status and the home port of the lifs. Verify all the lifs,routes in ngsh exists in SK and BSD. vserver and address parameters are mandatory to run in systemshell. interface parameter is mandatory in nodescope. =over =item Options =over =item C<< nacltask_verify => $boolean default - 0 >> (optional) Do all the verifications. =item C<< nacltask_verify_lifs_ngsh => $boolean default - 0 >> (optional)Do verification of lif exists in ngsh. =item C<< nacltask_verify_routes => $boolean default - 0 >> (optional)Do verification of existence of the routing-groups. =item C<< nacltask_verify_bsd => $boolean default - 0 >> (optional)Do verification of in systemshell. =item C<< nacltask_verify_nodescope => $boolean default - 0 >> (optional)Do verification of ifconfig in nodescope. =back Uses a CMode cli for all the verifications. Uses a 7Mode cli for ifconfig & route verification. Examples: *Verifying vserver, role, home-port, home-node of a lif in CDB and RDB (ngsh) network_configurations_check( command_interface => $Node, lif => $Lif, vserver => $Vserver, role => 'data', 'home-node' => $Node->name(), 'home-port' => $Free_port, address => $Address, netmask => $Netmask, nacltask_verify_lifs_ngsh => 1, ); *Verify routing group of a lif in cdb/rdb network_configurations_check( command_interface => $Nodes[0], lif => $Lif, vserver => $Vserver, 'routing-group' => $Routing_Group, nacltask_verify_lifs_ngsh => 1, ); *Verifying status-oper,vserver(cmode), ipaddress on systemshell network_configurations_check( command_interface => $Nodes[0], vserver => $Vserver, #required parameter role => 'data', address => $Address, #required parameter netmask => $Netmask, 'status-oper' => 'up', nacltask_verify_bsd => 1, ); *Verification of interface, ipaddress, netmask and status-oper in nodescope network_configurations_check( command_interface => $Nodes[0], interface => $Free_p_ports[0], #required parameter address => $Address, netmask => $Netmask, 'status-oper' => 'up', nacltask_verify_nodescope => 1, ); =back =cut sub network_configurations_check { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { command_interface => { isa => 'NACL::C::CommandInterface' }, nacltask_verify => { type => BOOLEAN, default => 0 }, nacltask_verify_routes => { type => BOOLEAN, default => 0 }, nacltask_verify_bsd => { type => BOOLEAN, default => 0 }, nacltask_verify_lifs_ngsh => { type => BOOLEAN, default => 0 }, nacltask_verify_nodescope => { type => BOOLEAN, default => 0 }, }, allow_extra => 1 ); my $command_interface = $opts{command_interface}; my $verify = delete $opts{nacltask_verify}; my $verify_routes = delete $opts{nacltask_verify_routes}; my $verify_lifs_ngsh = delete $opts{nacltask_verify_lifs_ngsh}; my $verify_lifs_bsd = delete $opts{nacltask_verify_bsd}; my $verify_nodescope = delete $opts{nacltask_verify_nodescope}; my %common_args; NACL::MTask::MTask->_move_common_component_params_with_ci( source => \%opts, target => \%common_args, ); #extracting the cdb opions from common opts. my %cdb_allowed_options; NACL::C::Component->_hash_copy( source => \%opts, copy => [ qw( instance home-node home-port role curr-port status-admin status-oper failover-policy address netmask has-valid-id firewall-policy use-failover-group failover-group routing-group curr-node ) ], map => { 'lif' => 'lif-name' }, target => \%cdb_allowed_options, ); #verifying network interfaces on rdb and cdb only for CMode if ( ($verify_lifs_ngsh) || ( $verify && $command_interface->mode() =~ /CMode/i ) ) { try { my $interface = delete $opts{'interface'}; #verifying interfaces using network interfaces show #Thorows error if the entry doesn't exist my $verfiy_cdb = NACL::STask::NetworkInterface->find( command_interface => $common_args{command_interface}, filter => { %opts, }, ); #verifying lifs on cdb if the role of the lif is cluster my $cs = $verfiy_cdb->state( requested_fields => [qw(role)] ); if ( $cs->role() =~ /(cluster|mgmt)/ ) { #verifying interfaces using network interfaces cdb show NACL::C::NetworkInterfaceCdb->find( command_interface => $common_args{command_interface}, filter => { %cdb_allowed_options, }, ); } $opts{'interface'} = $interface; } ## end try catch NACL::APISet::Exceptions::ResponseException with { my $eo = shift; $eo->throw(); } } ## end if (($verify_lifs_ngsh... if ( ($verify_lifs_bsd) || ($verify) ) { if ($verify_routes) { NACL::STask::NetworkRoute::_taskverify_systemshell( %opts); } #verifying interfaces in bsd shell _taskverify_systemshell( command_interface => $common_args{command_interface}, %opts, ); } ## end if (($verify_lifs_bsd)... #CMode and 7Mode if ( ($verify_nodescope) || ($verify) ) { if ($verify_routes) { NACL::STask::NetworkRoute::_taskverify_nodescope( %opts); } #verifying interfaces in nodescope _taskverify_nodescope( command_interface => $common_args{command_interface}, %opts, ); } ## end if (($verify_nodescope... $Log->exit() if $may_exit; } ## end sub network_configurations_check =head2 _taskverify_systemshell NACL::MTask::NetworkUtils->_taskverify_systemshell( command_interface => $node, vserver => $vserver, address => $address, role => $role, 'status-oper' => $opstatus ... ); (Class or Instance method) This function takes vserver, address as parameters and verifies the appropriate fields in systemshell & according to the action throws the error message. =over =item Options =over =item C<< vserver => $vserver >> (Required) Name of the vserver. =item C<< address => $address >> (Required) Address of the interface. =item C<< role => $role >> (optional) role of the interface(cluster,mgmt,data). =item C<< status-oper => $opstatus >> (optional) Operational status. =item C<< netmask => $netmask >> (Optional) Netmask to be used. =back =back =cut sub _taskverify_systemshell { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'vserver' => { type => SCALAR, optional => 1 }, 'address' => { type => SCALAR }, }, allow_extra => 1 # To allow the common options through ); my $command_interface = delete $opts{command_interface}; my $verfiy_port_status; my $msg; #ip exists in BSD only if lif is up, changing the lif status to up if it is down if ( $command_interface->mode() =~ /CMode/i ) { $verfiy_port_status = NACL::STask::NetworkInterface->find( command_interface => $command_interface, filter => { vserver => $opts{'vserver'}, address => $opts{'address'}, 'status-admin' => 'down' }, allow_empty => '1', ); if ($verfiy_port_status) { #status-admin of lif is down.. modifying lif status to make it visible in free bsd $verfiy_port_status->modify( 'status-admin' => 'up' ); } } ## end if ($command_interface... my $apiset = $command_interface->apiset( category => 'Node', interface => 'CLI', set => 'Systemshell' ); $apiset->set_privilege( "privilege-level" => "root" ); my $response = $apiset->ifconfig( 'all' => 1 ); my $output = $response->get_parsed_output(); my ( %result_hash, $verified, $allowed_bsd_options ); #vserver and address are the mandatory params to run on CMode systemshell if ( !( $opts{'vserver'} && $opts{'address'} ) && $command_interface->mode() =~ /CMode/i ) { require NACL::Exceptions::VerifyFailure; my $msg = "Verification failed on Systemshell! vserver and address are " . " mandatory params to run on CMode systemshell\n"; $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } my ( $interface, $lif_type, $flags, $netmask_hex ); foreach my $inet (@$output) { #if the ip address is not same as opts{address} skip the loop #(common for both CMode and 7Mode) my $ipv4 = $inet->{'ipv4'}; my $flag = 0; foreach my $addr (@$ipv4) { my $address = $addr->{'address'}; if ( $address eq $opts{'address'} ) { $flag = 1; $result_hash{'address'} = $address; } } next if ( $flag == 0 ); if ( $command_interface->mode() =~ /CMode/i ) { $allowed_bsd_options = [ qw( role status-oper address netmask routing-group vserver ) ]; #getting the vserver, routing-group from interface name $interface = $inet->{'name'}; if ( $interface =~ /(.*)_(.*)/ ) { $result_hash{'vserver'} = $1; $result_hash{'routing-group'} = $2; } #if the vserver is not same as opts{vserver} skip the loop next if ( $result_hash{'vserver'} !~ /$opts{'vserver'}/ ); $lif_type = $inet->{'ipv4'}->[0]->{'lif_type'}; if ( $lif_type =~ /CLUSTERLIF/ ) { $result_hash{'role'} = 'cluster'; } elsif ( $lif_type =~ /DATALIF/ ) { $result_hash{'role'} = 'data'; } elsif ( $lif_type =~ /NODEMGMTLIF/ ) { $result_hash{'role'} = 'node-mgmt'; } elsif ( $lif_type =~ /CSERVERMGMTLIF/ ) { $result_hash{'role'} = 'cluster-mgmt'; } } else { #filling result hash with 7Mode specific options $allowed_bsd_options = [ qw( status-oper address netmask broadcast ipspace mtu-size ) ]; $result_hash{'mtu-size'} = $inet->{'mtu'}; $result_hash{'broadcast'} = $inet->{'ipv4'}->[0]->{'broadcast'}; $result_hash{'ipspace'} = $inet->{'name'}; } ## end else [ if ($command_interface... #fetching the operational status from flags #(common for both CMode and 7Mode) $flags = $inet->{'flags'}; if ( $flags =~ /\w+{'ipv4'}->[0]->{'netmask'} ); foreach my $attrib (@$allowed_bsd_options) { if ( defined $opts{$attrib} && $opts{$attrib} ne $result_hash{$attrib} ) { require NACL::Exceptions::VerifyFailure; $msg = "Verification failed on Systemshell! as the value of $attrib is not reflecting in the Systemshell\n"; $Log->exit() if $may_exit; if ($verfiy_port_status) { $verfiy_port_status->modify( 'admin-status' => 'down' ); } NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } ## end if (defined $opts{$attrib... $verified = 1; } ## end foreach my $attrib (@$allowed_bsd_options) } ## end foreach my $inet (@$output) if ( !$verified ) { if ($verfiy_port_status) { $verfiy_port_status->modify( 'admin-status' => 'down' ); } $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } if ($verfiy_port_status) { $verfiy_port_status->modify( 'admin-status' => 'down' ); } $Log->exit() if $may_exit; } ## end sub _taskverify_systemshell =head2 _taskverify_nodescope NACL::MTask::NetworkUtils->_taskverify_nodescope( command_interface => $node, interface => $interface, address => $address, 'status-oper' => $opstatus ... ); (Class or Instance method) This function takes vserver, address as parameters and verifies the appropriate fields in nodescope & according to the action throws the error message. =over =item Options =over =item C<< interface => $interface >> (Required) Interface to be used. =item C<< address => $address >> (Optional) Address of the interface. =item C<< status-oper => $opstatus >> (optional) Operational status. =item C<< netmask => $netmask >> (Optional) Netmask to be used. =back =back =cut sub _taskverify_nodescope { $Log->enter() if $may_enter; my %opts = validate_with( params => \@_, spec => { 'command_interface' => { type => OBJECT }, 'interface' => { type => SCALAR }, }, allow_extra => 1 # To allow the common options through ); my $command_interface = delete $opts{command_interface}; my $nodescope_apiset = $command_interface->get_7m_or_nodescope_apiset(); my $response = $nodescope_apiset->ifconfig( 'all' => 1 ); my $output = $response->get_parsed_output(); my $msg; my $allowed_nodescope_options = [qw( interface address broadcast netmask mtu status-oper )]; my ( %result_hash, $verified, $addr_flag,$mask_flag ); $addr_flag = 0; $mask_flag = 0; foreach my $inet (@$output) { $result_hash{'interface'} = $inet->{'name'}; next if ( $result_hash{'interface'} !~ /$opts{'interface'}/ ); $result_hash{'flowcontrol'} = $inet->{'flowcontrol'}; $result_hash{'ipv4'} = $inet->{'ipv4'}; #arrayref of ipv4 addresses $result_hash{'ipv6'} = $inet->{'ipv6'}; #arrayref of ipv5 addresses $result_hash{'broadcast'} = $inet->{'broadcast'}; $result_hash{'mtu'} = $inet->{'mtu'}; $result_hash{'ipv4_info'} = $inet->{'ipv4_info'}; if ( exists( $inet->{'flags'}->[0]->{'UP'} ) ) { $result_hash{'status-oper'} = "up"; } else { $result_hash{'status-oper'} = "down"; } foreach my $attrib (@$allowed_nodescope_options) { if ( $attrib eq "address" && defined $opts{$attrib} ) { foreach my $addr ( @{ $result_hash{'ipv4'} } ) { $addr_flag = 1 if ( $addr eq $opts{$attrib} ); } if ( $addr_flag == 0 ) { require NACL::Exceptions::VerifyFailure; $msg = "Verification failed : the value $opts{$attrib} of $attrib is not reflecting in the nodescope\n"; $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } } elsif ( $attrib eq "netmask" && defined $opts{$attrib} ) { foreach my $mask ( @{ $result_hash{'ipv4_info'} } ) { $mask_flag = 1 if ( (_calc_netmask( $mask->{'mask'} )) eq $opts{$attrib} ); } if ( $mask_flag == 0 ) { require NACL::Exceptions::VerifyFailure; $msg = "Verification failed : the value $opts{$attrib} of $attrib is not reflecting in the nodescope\n"; $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw($msg); } } elsif ( defined $opts{$attrib} && $opts{$attrib} ne $result_hash{$attrib} ) { require NACL::Exceptions::VerifyFailure; $msg = "Verification failed : the value $opts{$attrib} of $attrib is not reflecting in the nodescope\n"; $Log->exit() if $may_exit; NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } $verified = 1; } ## end foreach my $attrib (@$allowed_nodescope_options) } ## end foreach my $inet (@$output) if ( !$verified ) { NACL::Exceptions::VerifyFailure->throw($msg) if ($msg); } $Log->exit() if $may_exit; } ## end sub _taskverify_nodescope sub _calc_netmask { my $netmask_hex = shift; my $netmask = ''; for ( my $i = 2; $i < 9; $i = $i + 2 ) { my $hex = substr( $netmask_hex, $i, 2 ); $netmask = $netmask . "." . hex $hex; } $netmask = substr( $netmask, 1 ); return $netmask; } ## end sub _calc_netmask 1;